/* ==========================================================================
   Black Marker — Components
   ========================================================================== */

/* --- Redaction bar --------------------------------------------------------
   The signature. Popcorn's system leans on the pill; ours leans on the
   redaction mark, because that is what the logo already is. Wrapping any
   word in .redact covers it with a black bar that slides away on hover,
   which demonstrates the product inside the brand.                       */

.redact {
  position: relative;
  display: inline-block;
  isolation: isolate;
  white-space: nowrap;
  max-width: 100%;
  /* The bar is sized to this inline-block's box. Inheriting a loose paragraph
     leading (1.85 in the document demo) made bars on consecutive lines touch
     and merge into slabs, so pin it to the glyphs instead. */
  line-height: 1.2;
  /* text-indent is inherited, and an inline-block is a block container, so a
     hanging-quote indent on the paragraph shifts these glyphs out of their own
     box and the bar stops covering the first character. Reset it here. */
  text-indent: 0;
  /* The bar bleeds sideways past the glyphs, which ate most of the word space
     next to it: measured, only 0.10em of a 0.25em space survived, so bars read
     as fused to the neighbouring word. This margin hands the space back
     without narrowing the bar further. */
  margin-inline: 0.08em;
}
.redact::after {
  content: "";
  position: absolute;
  /* Sized from the type, not from the line box, so one rule holds from 14px
     body copy to an 88px headline. Driving it from the box made the bar 77px
     tall inside a 64px line.

     The numbers are measured, not eyeballed. .redact pins its own line-height
     to 1.2, so the baseline always lands 0.9875em below the box top (0.965em
     in Inter). Across every redacted string on the page the tallest ascender
     reaches 0.77em above the baseline and the deepest descender 0.24em below,
     so the ink occupies 0.195em to 1.2275em from the box top. This spans
     0.12em to 1.29em, clearing both ends by about 0.07em. */
  /* Side bleed is deliberately smaller than the vertical: a wide bar collides
     with adjacent words and, where punctuation follows with no space, covered
     it outright. 0.10em still clears the glyphs on both sides. */
  left: -0.1em;
  right: -0.1em;
  top: 0.12em;
  bottom: auto;
  height: 1.17em;
  z-index: 1;
  background: var(--ink);
  border-radius: 2px;
  /* Hover lifts the bar off to the right. An intro sweep sets this to the left
     so the bar reads as being applied rather than removed. */
  transform-origin: var(--redact-origin, right center);
  transition: transform var(--dur-slow) var(--ease);
}
.redact:hover::after,
.redact:focus-visible::after { transform: scaleX(0); }

/* Static bar that never lifts, for the wordmark and decorative use. */
.redact-solid::after { transition: none; }
.redact-solid:hover::after { transform: none; }

/* Pre-redaction state: highlighted, not yet covered. */
.redact-pending {
  background: var(--highlight);
  border-radius: 2px;
  padding: 0.06em 0.16em;
  box-decoration-break: clone;
}

/* --- Wordmark ------------------------------------------------------------- */

/* The real mark from blackmarker.com, vector-traced from their raster original
   so it stays crisp at any size. A hand-drawn marker stroke with torn edges and
   the name knocked out of it. Driven as a CSS mask so it inherits
   currentColor and works on light and dark without a second asset. The
   letters stay transparent, so whatever is behind shows through them. */
.wordmark {
  display: block;
  width: var(--wordmark-w, 168px);
  aspect-ratio: 1583 / 327;
  background-color: currentColor;
  -webkit-mask: url("../assets/blackmarker-wordmark.svg") center / contain no-repeat;
          mask: url("../assets/blackmarker-wordmark.svg") center / contain no-repeat;
}
.wordmark-lg { --wordmark-w: 260px; }

/* --- Buttons --------------------------------------------------------------
   Pill geometry from the reference. Note the reference sets its large
   buttons in the SERIF face, which is unusual and a big part of why the
   site feels considered rather than templated. We keep that.            */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  padding: 0.75rem 1.5rem;
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  font-family: var(--font-sans);
  font-size: var(--text-base);
  font-weight: var(--weight-medium);
  letter-spacing: var(--track-tight);
  line-height: 1.25;
  cursor: pointer;
  transition: background var(--dur) var(--ease),
              color var(--dur) var(--ease),
              border-color var(--dur) var(--ease),
              transform var(--dur-fast) var(--ease);
}
.btn:active { transform: translateY(1px); }

.btn-primary { background: var(--ink); color: var(--surface); }
.btn-primary:hover { background: var(--ink-2); }

.btn-ghost {
  background: transparent;
  color: var(--ink);
  border-color: var(--hairline-2);
}
.btn-ghost:hover { background: var(--surface); border-color: var(--ink); }

.btn-mint { background: var(--mint); color: var(--ink); }
.btn-mint:hover { background: var(--mint-deep); color: var(--surface); }

/* Large hero button, set in the display serif but at Regular — it is a control,
   not a heading, and Medium reads too insistent at button size. */
.btn-lg {
  font-family: var(--font-display);
  font-size: var(--display-xs);
  font-weight: var(--weight-regular);
  padding: 0.7rem 1.9rem;
}

/* --- Badge / pill --------------------------------------------------------- */

.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  /* Fixed to the same 2rem as .step-num. Padding alone made the pill 34.2px,
     which grew step card two's number row and dropped its heading and body
     copy 2px below the other two cards. */
  height: 2rem;
  padding: 0 0.85rem;
  border: 1px solid var(--hairline-2);
  border-radius: var(--radius-pill);
  background: var(--surface);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--ink-3);
}
.badge-dot::before {
  content: "";
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--mint);
}
.badge-solid { background: var(--ink); color: var(--surface); border-color: var(--ink); }

/* --- Cards ---------------------------------------------------------------- */

.card {
  background: var(--surface);
  /* A card must re-assert its own text colour. Without this it inherits from
     a dark parent (.cta-panel, .footer-reveal) and renders white on white. */
  color: var(--ink);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-outer);
  padding: var(--s-8);
  box-shadow: var(--shadow);
  transition: box-shadow var(--dur) var(--ease),
              transform var(--dur) var(--ease);
}
.card-hover:hover {
  box-shadow: var(--shadow-lift);
  transform: translateY(-2px);
}

.card-lg   { border-radius: var(--radius-outer); padding: var(--s-10); }
.card-flat { box-shadow: none; }
.card-dark { background: var(--ink); color: var(--surface); border-color: transparent; }
.card-dark .muted, .card-dark .lead { color: rgba(255, 255, 255, 0.62); }
.card-dark .caps { color: rgba(255, 255, 255, 0.5); }
.card-mint { background: var(--mint-wash); border-color: transparent; box-shadow: none; }

/* --- Nav ------------------------------------------------------------------
   The current site's nav is the thing Austin called clunky. This is a
   floating pill bar: hairline border, blurred backdrop, one dark CTA.   */

/* No white pill. The nav sits directly on the page so the wash runs behind
   it uninterrupted; only a hairline separates it once you scroll. */
.nav {
  position: sticky;
  top: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-6);
  padding: var(--s-5) 0;
  background: transparent;
  transition: border-color var(--dur) var(--ease);
  border-bottom: 1px solid transparent;
}
.nav[data-stuck="true"] {
  border-bottom-color: var(--hairline);
  backdrop-filter: saturate(1.4) blur(10px);
}
.nav-links { display: flex; gap: var(--s-6); }
.nav-links a {
  font-size: var(--text-base);
  font-weight: var(--weight-medium);
  color: var(--ink-3);
  transition: color var(--dur) var(--ease);
}
.nav-links a:hover, .nav-links a[aria-current="page"] { color: var(--ink); }

/* Below the nav-links breakpoint the bar is wordmark + CTA only, so it has
   to stop the CTA wrapping and tighten its own padding. */
.nav .btn { white-space: nowrap; }

@media (max-width: 760px) {
  .nav-links { display: none; }
  .nav { padding: var(--s-4) 0; gap: var(--s-3); }
  .nav .btn { padding: 0.6rem 1rem; font-size: var(--text-sm); }
  .wordmark { --wordmark-w: 132px; }
}

/* --- Numbered step -------------------------------------------------------- */

.step-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem; height: 2rem;
  border-radius: var(--radius-pill);
  background: var(--ink);
  color: var(--surface);
  font-size: var(--text-sm);
  font-weight: var(--weight-semi);
  line-height: 1;
}

/* --- Stat ----------------------------------------------------------------- */

.stat-value {
  font-family: var(--font-display);
  font-size: var(--display-m);
  font-weight: var(--display-weight);
  line-height: var(--leading-flat);
  letter-spacing: var(--track-display);
}

/* --- Quote ---------------------------------------------------------------- */

/* Pull quotes are the one place the display face runs at Regular with open
   leading and no negative tracking — set for reading, not for impact. */
.quote {
  font-family: var(--font-display);
  font-size: var(--display-s);
  font-weight: var(--quote-weight);
  font-stretch: var(--quote-width);
  line-height: var(--leading-quote);
  letter-spacing: 0;
  text-wrap: pretty;
}

/* --- Form ----------------------------------------------------------------- */

.field {
  width: 100%;
  padding: 0.75rem 1rem;
  background: var(--surface);
  border: 1px solid var(--hairline-2);
  border-radius: var(--radius-sm);
  font-family: var(--font-sans);
  font-size: var(--text-base);
  letter-spacing: var(--track-tight);
  color: var(--ink);
  transition: border-color var(--dur) var(--ease);
}
.field::placeholder { color: var(--ink-4); }
.field:focus { outline: none; border-color: var(--ink); }

.label {
  display: block;
  margin-bottom: var(--s-2);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
}

/* --- Divider -------------------------------------------------------------- */

.divider { height: 1px; background: var(--hairline); border: 0; margin: 0; }

/* --- Document preview -----------------------------------------------------
   Stands in for the live demo. Austin says the pre-loaded redaction demo is
   the real "aha" and it appears nowhere on the current homepage. This is
   the placeholder shape for it.                                         */

.doc {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-outer);
  padding: var(--s-8);
  box-shadow: var(--shadow);
  font-family: var(--font-display);
  font-size: clamp(var(--text-base), 1.4vw, var(--text-lead));
  line-height: 1.8;
  text-wrap: pretty;
}
.doc-line {
  height: 0.7em;
  background: var(--surface-3);
  border-radius: 3px;
  margin-block: 0.55em;
}
.doc-line.w-90 { width: 90%; } .doc-line.w-75 { width: 75%; }
.doc-line.w-60 { width: 60%; } .doc-line.w-40 { width: 40%; }

/* --- Reveal footer --------------------------------------------------------
   The page sits in a raised sheet. The dark footer is fixed behind it, so it
   is uncovered as you reach the bottom rather than scrolling into view. The
   sheet's bottom corners round off, which is what sells the depth.

   Requires --footer-h to match the footer's real height. `footer-reveal.js`
   measures it, and the CSS fallback below keeps the layout sane without JS. */

.sheet {
  position: relative;
  z-index: 1;
  background: var(--paper);
  /* display:flow-root contains child margins. Without it the nav's top margin
     collapsed out of the sheet and let the ink body background show as a strip
     above the page. */
  display: flow-root;
  border-end-start-radius: var(--radius-outer);
  border-end-end-radius: var(--radius-outer);
  margin-bottom: var(--footer-h, 34rem);
  overflow: clip; /* keeps the wash layers inside the rounded corners */
}

.footer-reveal {
  position: fixed;
  inset: auto 0 0 0;
  z-index: 0;
  background: var(--ink);
  color: var(--surface);
  /* Generous top padding: the sheet's bottom edge lands exactly on the footer's
     top edge, so anything less crowds the first row of links against it. */
  padding-block: var(--s-20) 0;
  overflow: hidden;   /* the oversized mark is clipped, never scrolls the page */
}
.footer-reveal a { color: rgba(255, 255, 255, 0.6); transition: color var(--dur) var(--ease); }
.footer-reveal a:hover { color: var(--surface); }
.footer-reveal .caps { color: var(--surface); }

/* The oversized wordmark that anchors the bottom of the reference's footer.
   Clipped deliberately: it reads as a watermark, not a heading. */
/* The oversized mark is the wordmark only — no marker block around it, in a
   grey one step off ink so it reads as a watermark rather than a second logo.

   Drawn as SVG: a viewBox scales to fill its container exactly at any width,
   which no font-size calculation can guarantee. This replaces two earlier
   attempts, one in vw and one in container units, both of which had to be
   tuned by hand and both of which drifted. */
.footer-mark {
  display: block;
  width: 100%;
  height: auto;
  /* The frame clips 6px off a 115px mark. A percentage resolves against the
     container's width, so the clip scales with the mark instead of eating
     more of it as the page narrows. */
  margin: var(--s-12) 0 -0.5%;
  fill: var(--ink-deep);
  user-select: none;
  pointer-events: none;
}
.footer-mark-text {
  font-family: var(--font-sans);
  font-weight: var(--weight-bold);
  line-height: 0.7373;     /* Inter's cap height: all caps, so no descender */
  letter-spacing: 0;
  text-align: center;
  color: var(--ink-deep);
  white-space: nowrap;
  width: 100%;
}

.footer-mark text {
  font-family: var(--font-sans);
  font-weight: var(--weight-bold);
  font-size: 100px;        /* viewBox units — the viewBox handles the scaling */
  letter-spacing: 0;       /* the frame sets the mark solid, not tracked out */
}

.footer-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  padding-top: var(--s-8);
  margin-top: var(--s-12);
  border-top: 1px solid rgba(255, 255, 255, 0.12);
}

/* No fixed positioning on short viewports: the reveal needs room to work. */
@media (max-height: 640px), (max-width: 600px) {
  .sheet { margin-bottom: 0; border-end-start-radius: 0; border-end-end-radius: 0; }
  .footer-reveal { position: static; }
}

/* --- FAQ accordion --------------------------------------------------------
   The reference answers objections inline near the end of the page, right
   before the last ask. The live Black Marker site has no FAQ at all, which
   for a compliance purchase means every objection has to be raised on a
   sales call instead of being handled on the page.

   Built on <details>/<summary> so it works with no JavaScript, is keyboard
   operable, and is announced correctly by screen readers. */

.faq { display: grid; gap: var(--s-3); }

.faq-item {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-outer);
  box-shadow: var(--shadow);
  overflow: hidden;
}

.faq-item > summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-6);
  padding: var(--s-5) var(--s-6);
  cursor: pointer;
  list-style: none;
  font-family: var(--font-display);
  font-size: var(--display-xs);
  font-weight: var(--display-weight-s);
  letter-spacing: var(--track-display);
  line-height: var(--leading-snug);
}
.faq-item > summary::-webkit-details-marker { display: none; }

.faq-item > summary::after {
  content: "";
  flex: none;
  width: 1.5rem; height: 1.5rem;
  border-radius: 50%;
  background: var(--surface-3);
  background-image:
    linear-gradient(var(--ink-3), var(--ink-3)),
    linear-gradient(var(--ink-3), var(--ink-3));
  background-size: 0.6rem 1.5px, 1.5px 0.6rem;
  background-position: center, center;
  background-repeat: no-repeat;
  transition: transform var(--dur) var(--ease);
}
.faq-item[open] > summary::after { transform: rotate(135deg); }

.faq-answer {
  padding: 0 var(--s-6) var(--s-6);
  color: var(--ink-3);
  max-width: 68ch;
  /* The section centres its heading, and the answer was inheriting that. */
  text-align: left;
}

/* Flags an answer the client still needs to supply. Never ship one of these. */
.faq-todo {
  display: inline-block;
  margin-top: var(--s-3);
  padding: 0.2rem 0.6rem;
  border-radius: var(--radius-pill);
  background: var(--highlight);
  color: var(--ink);
  font-size: var(--text-xs);
  font-weight: var(--weight-semi);
}

/* --- Proof bar ------------------------------------------------------------
   Numbers the client already owns but never shows. */

.proof {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--s-8);
  text-align: center;
}
@media (max-width: 700px) { .proof { grid-template-columns: 1fr; gap: var(--s-10); } }

/* --- Hanging punctuation --------------------------------------------------
   An opening quote mark sitting inside the text block pushes the first line
   right and breaks the left edge. Pulling it into the margin puts the first
   real letter in line with every line beneath it.

   Done with a negative first-line indent rather than the `hanging-punctuation`
   property, which only Safari supports. em units mean one class works at every
   type size; the value is roughly the advance width of a curly double quote. */

.quote-hang { text-indent: -0.42em; }

/* The sans faces carry a narrower quote than the serif. */
.body.quote-hang,
.small.quote-hang { text-indent: -0.34em; }


/* --- Testimonial mosaic ---------------------------------------------------
   Real masonry via multi-column, not a row grid. A row grid leaves dead space
   under every card shorter than the tallest in its row; columns let each card
   sit directly beneath the one above it, so the block packs tight and only the
   bottom edge rags.

   Every quote takes the same serif treatment — the cards differ in length, not
   in style. */

.mosaic {
  columns: 3;
  column-gap: var(--s-4);
}
.mosaic .card {
  break-inside: avoid;
  margin-bottom: var(--s-4);
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
}
.mosaic .quote { font-size: var(--display-xs); }

@media (max-width: 900px) { .mosaic { columns: 2; } }
@media (max-width: 600px) { .mosaic { columns: 1; } }

/* Attribution line. No top margin — the card's own gap owns that spacing. */
.who { display: flex; align-items: center; gap: var(--s-3); }
.who-mark {
  flex: none;
  width: 2.25rem; height: 2.25rem;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--surface-3);
  color: var(--ink-3);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
}
.src { font-size: var(--text-xs); color: var(--ink-4); }


/* --- Concentric radii -----------------------------------------------------
   A surface sitting inside another surface takes the smaller radius, so the
   inner curve reads as parallel to the outer one rather than competing. */

.card .card,
.panel .card,
.cta-panel .card,
.panel .g-frame,
.card .g-frame,
.panel .gate,
.panel .doc {
  border-radius: var(--radius-inner);
}

/* --- Document demo --------------------------------------------------------
   The hero's proof: a real document that redacts itself, with tabs showing the
   same engine across very different source material. Set in the sans, because
   this is meant to read as a system rendering a file, not as editorial. */

.doc-demo {
  max-width: 760px;
  margin-inline: auto;
  margin-top: var(--s-16);      /* clears the hero button */
}

.doc-panel {
  font-family: var(--font-sans);
  font-size: 1.375rem;          /* 22px — sized up in Figma on 2026-09-05 */
  line-height: 1.515;           /* 33.3px at 22px */
  letter-spacing: -0.02em;
  /* Optically equal padding on all four sides. The box padding is 32px, but a
     line box carries about 4px of half-leading above the ink and 6px below it,
     so the vertical padding is trimmed by those amounts. That lands the words
     33px from every edge, matching where the first glyph sits from the left.
     Measured on the live panel, not guessed. */
  padding: 29px 32px 27px;
  /* A floor only, for the no-JS case. The real lock is measured at the
     live width in the doc demo script, because the tallest of the four
     documents changes as the column narrows. */
  min-height: 12rem;
}

/* Word-by-word reveal. Each unit starts hidden and is released on a stagger
   set in JS, so the whole paragraph lands in about a second. */
.w {
  display: inline-block;
  opacity: 0;
  transform: translateY(0.22em);
  animation: word-in 0.34s var(--ease) forwards;
}
@keyframes word-in { to { opacity: 1; transform: none; } }

/* --- The three quick proofs -----------------------------------------------
   The frame insets this row to 992 inside the 1200 container, separates it
   from the caption with a hairline, and sets the caption narrow enough to
   break onto two lines rather than running the full width.               */

.proof-3 { padding-bottom: var(--s-12); }
.proof-inner { max-width: 992px; margin-inline: auto; }

.proof-rule {
  border: 0;
  height: 1px;
  background: var(--track);
  margin: 49px 0 0;
}

.proof-note {
  max-width: 13rem;              /* holds it to the frame's two lines */
  margin: 49px auto 0;
  text-align: center;
}

/* --- Tabs ----------------------------------------------------------------
   No stroke. The timing indicator is the tab's own background filling left to
   right in a shade barely off the page, so the switch is announced without a
   line or a border competing with the card above. */

.doc-tabs {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--s-6);
  padding-inline: var(--s-8);
  margin-top: var(--s-5);
}
@media (max-width: 620px) { .doc-tabs { grid-template-columns: repeat(2, 1fr); } }

.doc-tab {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  gap: var(--s-1);
  /* 13px of air under the labels, then the 3px rule. No inset: the frame
     sits the tabs flush and lets the rule carry the state. */
  padding: 0 0 16px;
  border: 0;
  background: transparent;
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  letter-spacing: var(--track-tight);
  text-align: left;
  cursor: pointer;
  transition: color var(--dur) var(--ease);
}
/* Every tab keeps its label at full strength. The rule below is the only
   thing that says which one is running, which is how the frame does it. */
.doc-tab::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 3px;
  border-radius: 6px;
  background: var(--track);
}

.doc-tab-label, .doc-tab-sub { position: relative; z-index: 1; }
.doc-tab-sub {
  font-size: var(--text-xs);
  font-weight: var(--weight-regular);
  color: var(--ink-4);
}

/* The fill IS the indicator: it runs along the track over the dwell. Width is
   driven in JS. */
.doc-tab-fill {
  position: absolute;
  left: 0; bottom: 0;
  z-index: 1;
  width: 0;
  height: 3px;
  border-radius: 6px;
  background: var(--ink);
}

@media (prefers-reduced-motion: reduce) {
  .w { opacity: 1; transform: none; animation: none; }
  .doc-tab-fill { transition: none; }
}
}
