/* ==========================================================================
   Black Marker — Atmosphere & Graphics
   Everything here is pure CSS and inline SVG. No image assets, so the whole
   system stays portable into whatever CMS the client's team picks.
   ========================================================================== */

/* --- Page texture ---------------------------------------------------------
   Applied ONCE to the sheet rather than per section. Two layers: a coarse
   watercolour blotch and a fine paper tooth. Doing it per section is what
   made the texture stop abruptly at the top of the page.                 */

.sheet::before,
.sheet::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}

/* Mid-scale fibre. This is the layer that reads as paper: irregular pigment
   catching on tooth. Tile is 420px so the repeat never resolves as a grid. */
.sheet::before {
  opacity: var(--mottle-opacity);
  mix-blend-mode: multiply;
  background-size: 420px 420px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='420' height='420'%3E%3Cfilter id='m'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.05' numOctaves='5' seed='17' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeComponentTransfer%3E%3CfeFuncA type='linear' slope='1.3' intercept='-.1'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='420' height='420' filter='url(%23m)'/%3E%3C/svg%3E");
}

/* Fine tooth on top of the fibre. */
.sheet::after {
  opacity: var(--grain-opacity);
  mix-blend-mode: multiply;
  background-size: 130px 130px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='130' height='130'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.2' numOctaves='3' seed='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='130' height='130' filter='url(%23g)'/%3E%3C/svg%3E");
}

/* Everything in the sheet sits above both texture layers. */
.sheet > * { position: relative; z-index: 1; }

/* --- Watercolour wash -----------------------------------------------------
   Colour only. The edges are feathered with a mask so a section's wash melts
   into the next instead of ending on a hard line.                        */

.wash, .atmos { position: relative; isolation: isolate; }

.wash::before,
.atmos::before {
  content: "";
  position: absolute;
  inset: -14% -6%;
  z-index: -1;
  pointer-events: none;
  filter: blur(var(--wash-blur));
  background:
    radial-gradient(46% 40% at 18% 22%, var(--wash-mint), transparent 70%),
    radial-gradient(40% 36% at 82% 14%, var(--wash-warm), transparent 72%),
    radial-gradient(52% 44% at 62% 86%, var(--wash-cool), transparent 74%);
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 16%, #000 84%, transparent 100%);
          mask-image: linear-gradient(to bottom, transparent 0%, #000 16%, #000 84%, transparent 100%);
}

.wash-warm::before {
  background:
    radial-gradient(52% 46% at 24% 16%, var(--wash-warm), transparent 72%),
    radial-gradient(44% 38% at 78% 28%, var(--wash-mint), transparent 72%);
}
.wash-cool::before {
  background:
    radial-gradient(54% 46% at 76% 18%, var(--wash-cool), transparent 74%),
    radial-gradient(40% 34% at 16% 72%, var(--wash-mint), transparent 72%);
}

/* The hero is the top of the page, so its wash must not fade in from nothing
   at the very top — only out at the bottom. */
.atmos-top::before {
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 76%, transparent 100%);
          mask-image: linear-gradient(to bottom, #000 0%, #000 76%, transparent 100%);
}

/* --- Icon chip ------------------------------------------------------------
   A circle with a soft radial fill, so the icon sits in light rather than
   on a flat disc. Straight from the reference.                           */

.icon-chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3.25rem;
  height: 3.25rem;
  flex: none;
  border-radius: 50%;
  color: var(--ink);
  /* A plain white disc with a barely-there lift, straight off the frame:
     0/8/8 at -20 spread and 3% opacity. It reads as a soft hole in the page
     rather than a button, which the old two-gradient chip did not. */
  background: var(--surface);
  box-shadow: 0 8px 8px -20px rgba(15, 30, 60, 0.03);
}
.icon-chip svg { width: 1.35rem; height: 1.35rem; display: block; overflow: visible; }

/* The small chip sits on a card rather than the page, so it takes the paper
   colour and no lift at all. */
.icon-chip-sm { width: 2.5rem; height: 2.5rem; background: var(--paper); box-shadow: none; }
.icon-chip-sm svg { width: 1.1rem; height: 1.1rem; }

/* Chips are used inside centred columns as often as inline, so give them a
   reliable way to centre without every caller writing the same rule. */
.icon-chip-center { display: flex; margin-inline: auto; }


/* --- Panel ----------------------------------------------------------------
   The big rounded container that groups a section. One treatment, used
   everywhere: a flat 3% black wash on the paper. It was three different
   gradients (cool grey, mint, warm) until the frame showed every panel on
   the same neutral wash — the tints were reading as meaning that wasn't
   there.                                                                 */

.panel {
  border-radius: var(--radius-outer);
  padding: clamp(var(--s-8), 4vw, var(--s-16));
  background: var(--wash);
}

/* --- Supporting graphics --------------------------------------------------
   Small compositions that carry an idea. Each one is a diagram of a claim
   the copy makes, not decoration.                                        */

.g-frame {
  background: var(--surface);
  border-radius: var(--radius-outer);
  padding: var(--s-6);
  box-shadow: var(--shadow);
}

/* Detection: text scanned, flagged, then covered. The highlight sweeps in from
   the left like a scan head passing over the line, then the bars land the same
   way. Loops, because it is describing what happens to every page. */
.g-detect { font-family: var(--font-display); font-size: var(--text-sm); line-height: 2; }

.g-detect .redact-pending {
  background-color: transparent;
  background-image: linear-gradient(var(--highlight), var(--highlight));
  background-repeat: no-repeat;
  background-size: 0% 100%;
  transition: background-size 0.42s var(--ease);
}
.g-detect.is-scanned .redact-pending { background-size: 100% 100%; }

/* During the intro the bars sweep on from the left. */
.g-detect .redact { --redact-origin: left center; }
.g-detect .redact::after { transform: scaleX(0); }
.g-detect.is-redacted .redact::after { transform: scaleX(1); }
/* Once the intro has run, hand the origin back so hover lifts to the right. */
.g-detect.is-armed .redact { --redact-origin: right center; }

@media (prefers-reduced-motion: reduce) {
  .g-detect .redact-pending { background-size: 100% 100%; }
  .g-detect .redact::after { transform: scaleX(1); }
}

/* Metadata stripping ------------------------------------------------------
   A property list that empties out. Rows arrive on a stagger, then each value
   is struck through by a line drawn left to right — the same left-to-right
   erasure the redaction bars use, at a smaller scale. It loops, because the
   claim is that this happens on every document, not once. */

.g-meta-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s-4); padding: var(--s-2) 0;
  border-bottom: 1px solid var(--hairline);
  font-size: var(--text-sm);
  opacity: 0;
  transform: translateY(0.35em);
  transition: opacity 0.4s var(--ease), transform 0.4s var(--ease);
}
.g-meta-row:last-child { border-bottom: 0; }
.g-meta.is-in .g-meta-row { opacity: 1; transform: none; }

.g-meta-key { color: var(--ink-3); }
.g-meta-val { font-variant-numeric: tabular-nums; }

/* The strike is a drawn line, not text-decoration, so it can be animated. */
.g-meta-stripped {
  position: relative;
  color: var(--ink-3);
  transition: color 0.5s var(--ease);
}
.g-meta-stripped::after {
  content: "";
  position: absolute;
  left: -0.16em; right: -0.16em;
  top: 54%;
  height: 1.5px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.5s var(--ease);
}
.g-meta-row.is-struck .g-meta-stripped { color: var(--ink-4); }
.g-meta-row.is-struck .g-meta-stripped::after { transform: scaleX(1); }

/* The surviving row resolves rather than disappears. */
.g-meta-out { color: var(--ink-4); transition: color 0.5s var(--ease); }
.g-meta.is-done .g-meta-out {
  color: var(--mint-deep);
  font-weight: var(--weight-semi);
}

@media (prefers-reduced-motion: reduce) {
  .g-meta-row { opacity: 1; transform: none; }
  .g-meta-stripped::after { transform: scaleX(1); }
}

/* Throughput gate ---------------------------------------------------------
   Pages stream left to right through a redaction gate: they arrive with their
   content readable and leave with bars over it. Shows the product working, not
   just a quantity. Replaced a tile grid that went solid black once it filled,
   which read as a rectangle rather than as scale. */

.gate {
  position: relative;
  height: 190px;
  overflow: hidden;
  border-radius: var(--radius-outer);
  background: var(--surface-2);
  border: 1px solid var(--hairline);
}

.gate-line {
  position: absolute;
  left: 50%; top: 0; bottom: 0;
  width: 2px;
  background: var(--ink);
  z-index: 3;
}

.gate-label {
  position: absolute;
  left: 50%; top: 10px;
  transform: translateX(-50%);
  z-index: 4;
  padding: 3px 10px;
  border-radius: var(--radius-pill);
  background: var(--ink);
  color: var(--surface);
  font-size: var(--text-xs);
  font-weight: var(--weight-semi);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  white-space: nowrap;
}

/* A single page in the stream. */
.gate-pg {
  position: absolute;
  width: 52px; height: 66px;
  padding: 6px 5px;
  border-radius: 3px;
  background: var(--surface);
  border: 1px solid var(--hairline-2);
  box-shadow: var(--shadow);
  animation: gate-drift 5.2s linear infinite;
}
.gate-pg i {
  display: block;
  height: 3px;
  margin-bottom: 4px;
  border-radius: 1px;
  background: var(--surface-3);
}
.gate-pg i.r { background: var(--ink); }

@keyframes gate-drift {
  from { transform: translateX(-70px); }
  to   { transform: translateX(760px); }
}

/* Everything past the gate line is clipped to this half, and holds the
   redacted copy of each page. Crossing the line converts it. */
.gate-after {
  position: absolute;
  inset: 0 0 0 50%;
  overflow: hidden;
  z-index: 2;
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  .gate-pg { animation: none; }
}

/* Static capture mode: no motion anywhere, everything in its resolved state. */
html[data-static] .gate-pg { animation: none !important; }
html[data-static] *, html[data-static] *::before, html[data-static] *::after {
  animation-play-state: paused !important;
  transition: none !important;
}

/* Coverage list, the flag-row pattern from the reference. */
.g-cover-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s-4); padding: var(--s-3) 0;
  border-bottom: 1px solid var(--hairline);
}
.g-cover-row:last-child { border-bottom: 0; }
