/* ==========================================================================
   FRONTLINE21 — THE INK
   Quantico Bold is red, and it is printed.

   The rule, from the 6 September direction: most of the time, anything set
   in Quantico Bold is Frontline red on the charcoal, carrying the printed
   material of the Wall of Truth. White is used on Quantico only where
   contrast requires it, which on this ground means the small sizes: labels,
   controls and indexes, where red would not clear 4.5:1.

   THE CORRECTION OF 8 SEPTEMBER, EVENING

   Two things in the previous stack were the wrong effect, and both are gone.

   The wear was an ALPHA mask. It made parts of the letter transparent, so the
   page showed through the ink; at the strongest grade that is not thin ink,
   it is a hole. "Do not substitute coarse holes punched through the
   lettering... Broad background-colored perforations are the wrong effect."

   Beside it sat a warm light — a moving radial gradient on a screen blend,
   in rgba(255, 236, 214) — which brightened the ink toward white. That is the
   pale, bleached appearance that was asked to go. It also travelled: the
   print was only itself at one moment of a twenty two second cycle, and the
   brief is explicit that "the printed wear must be visible in the ordinary
   settled state, not only during an animation event".

   What replaces both is one grayscale density field, MULTIPLIED over the core
   red inside the text clip. Multiply cannot make a hole and cannot make a
   highlight. Every printed pixel is #DC2227 or a slightly darker red of the
   same family; the lightest interior value is the core red exactly; the
   deepest wear is 78% of it; and the material is stable, so a settled
   headline is printed whether or not anything is animating.

   The field is generated by tools/make-ink-print.py from a measurement of the
   supplied reference, not from a sampling of it: 81% of a glyph interior is
   the core red untouched, 89% is within 10% of it, 11% is the worn ink, and
   1.2% is more than 14% down. The worn areas are soft-edged plateaux with a
   scatter of finer breaks inside them, at three spatial scales relative to
   the cap height, because what makes printing read as worn is that the loss
   is organised — not that every pixel is very slightly off.

   THE TWO HOOKS
     [data-ink]   the print layer: the element that holds the declaration. It
                  carries the red.
     .ink         the surface: an inline wrapper inside it around the words.
                  With background-clip: text it multiplies the density field
                  inside the letterforms.

   THE TWO MEASUREMENTS ink.js writes on the print layer
     data-ink-tier  0 to 5, from the settled CSS pixel size and the layout
                    width. Tier 0 is clean type.
     --ink-mask     the tile's rendered size in px, held at 3.8x the type's
                    size. The generator authors the field for that ratio, so
                    a worn area is the same size relative to a letter on a
                    30 px heading as on a 200 px statement. Getting this ratio
                    wrong is what made the first attempt at this correction
                    look like a haze rather than like print.

   Nothing here can hide a word, and nothing here can paint a rectangle: every
   background layer lives inside the rule that clips it, and ink.js reads the
   clip back and removes is-printed if it did not survive.
   ========================================================================== */

:root {
  /* The ink's own red IS the identity red now.

     It used to be lifted to #e62a30, because the old stack darkened the ink
     almost everywhere and the base had to start above where it would land.
     The density field only ever multiplies, and its top is 1.0, so the base
     is what the majority of every letter actually renders as: the approved
     token, unmodified.

     Measured on the #121616 ground: the core is 3.73:1, the knee at 90% is
     3.14:1, and the deepest isolated wear at 78% is 2.44:1 over 1.2% of a
     glyph's area. The bulk of every letter clears the 3:1 large-text floor.

     Reproduce with tools/measure-ink.py. */
  --ink-red: #dc2227;        /* the identity red, for flat type and interface */
  --ink-red-print: #dc2227;  /* the base the printed stack starts from */

  /* Defaults, so a print layer renders sanely for the frame before ink.js
     has measured it. */
  --ink-mask: 512px;
  --ink-print: url('../images/texture/f21-ink-print-25-512.png');
}

/* --- The print layer ------------------------------------------------------ */

[data-ink] {
  color: var(--ink-red);
}

[data-ink] em,
[data-ink] b,
[data-ink] i {
  color: inherit;
  font-style: inherit;
  font-weight: inherit;
}

/* The grades. One material, five depths of wear: see tools/make-ink-print.py.
   Desktop and tablet are the layout at 768 CSS px and above; ink.js decides
   which of the two columns a print layer is in and writes the tier, so these
   are plain tier selectors rather than media queries. The percentage in each
   filename is the share of the field's full departure from the core that
   survives, so -25 is a quarter of the wear, not a quarter of the ink. */
[data-ink-tier='1'] { --ink-print: url('../images/texture/f21-ink-print-25-512.png'); }
[data-ink-tier='2'] { --ink-print: url('../images/texture/f21-ink-print-25-512.png'); }
[data-ink-tier='3'] { --ink-print: url('../images/texture/f21-ink-print-50-512.png'); }
[data-ink-tier='4'] { --ink-print: url('../images/texture/f21-ink-print-50-512.png'); }
[data-ink-tier='5'] { --ink-print: url('../images/texture/f21-ink-print-100-512.png'); }

/* The phone column of the same table. ink.js writes data-ink-phone alongside
   the tier when the layout is under 768 px. A phone renders the same
   declaration smaller, so the same physical wear covers fewer device pixels
   and has to be gentler or it reads as dirt. */
[data-ink-phone][data-ink-tier='2'] { --ink-print: url('../images/texture/f21-ink-print-20-512.png'); }
[data-ink-phone][data-ink-tier='3'] { --ink-print: url('../images/texture/f21-ink-print-20-512.png'); }
[data-ink-phone][data-ink-tier='4'] { --ink-print: url('../images/texture/f21-ink-print-40-512.png'); }
[data-ink-phone][data-ink-tier='5'] { --ink-print: url('../images/texture/f21-ink-print-80-512.png'); }

/* --- The surface ------------------------------------------------------------ */

/* Inside a heading the surface is the heading's whole block, so its material
   spans every line rather than each line fragment. The one exception is the
   hero title, whose lines rise into view inside clipped spans: a clipped or
   transformed descendant is left out of a text clip, so there each rising
   line is its own surface. */
h1 > .ink,
h2 > .ink,
h3 > .ink,
p > .ink {
  display: block;
  overflow: visible;
}

@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  /* WHICH TIERS ARE CLIPPED, AND WHY ONLY THESE — 9 September.
     
     Tiers 1 and 2 are no longer painted through a text clip. Their grade of
     the material bottoms out at 0.945 of the core red — a four per cent
     darkening on type of 24 to 30 px — which is not visible at that size, and
     it was being bought with the one failure mode this technique has: a
     glyph run whose clipped background does not survive a repaint has no ink
     of its own to fall back on.
     
     That is what put HOME, WORK and COMMUNITY on the Homefront in pure white
     with NEIGHBORHOOD split mid-word, in Safari, on 9 September. Those six
     labels are tier 1. They are plain red now: no clip, no transparent fill,
     nothing to lose.
     
     Tiers 3 to 5 keep the clip, because at 32 px and up the wear is the point.
     Their fallback is hardened below.
     
     Tier 0 is clean type and never enters this rule. Two layers, both
     declared inside the clip: the density field, multiplied, over the flat
     core red. There is no background-color anywhere, so an engine that drops
     the clip has no rectangle to paint, and no lighten or screen anywhere, so
     nothing in the stack can produce a value above the core red. */
  html.is-printed [data-ink-tier='3'] .ink,
  html.is-printed [data-ink-tier='4'] .ink,
  html.is-printed [data-ink-tier='5'] .ink {
    /* Red, not transparent. -webkit-text-fill-color is what actually reveals
       the background; color is the value that paints if that one declaration
       is ever dropped. Between them there is no state in which a printed
       glyph renders as anything but red or as the material itself. It is
       never white and never the initial colour, which under this page's dark
       color-scheme IS white. */
    color: var(--ink-red-print);
    -webkit-text-fill-color: transparent;
    background-image:
      var(--ink-print),
      linear-gradient(var(--ink-red-print), var(--ink-red-print));
    background-size: var(--ink-mask) var(--ink-mask), 100% 100%;
    background-repeat: repeat, no-repeat;
    background-position: var(--wear-u, 0%) var(--wear-v, 0%), 0 0;
    background-blend-mode: multiply, normal;
    -webkit-background-clip: text;
    background-clip: text;
  }
}

/* --- Contrast ----------------------------------------------------------------- */

@media (forced-colors: active) {
  html.is-printed .ink {
    color: CanvasText;
    -webkit-text-fill-color: CanvasText;
    background: none;
  }
}

/* --- The resting state, guaranteed -------------------------------------------
   Every intended red print layer is red at rest by construction: the red is on
   [data-ink] itself, tiers 1 and 2 take it directly, and tiers 3 to 5 carry it
   as their own colour underneath the fill that reveals the material. Nothing in
   this file sets a print layer white, and nothing leaves one with no colour of
   its own.

   The one thing left that could show white is the INITIAL colour, which under
   color-scheme: dark is white. It is reachable only if an engine drops both
   the print layer's colour and the surface's — which is why the declaration is
   made twice, on the layer and on the surface, from the same token. */
[data-ink] .ink { color: inherit; }

html.is-printed [data-ink-tier='3'] .ink,
html.is-printed [data-ink-tier='4'] .ink,
html.is-printed [data-ink-tier='5'] .ink { color: var(--ink-red-print); }
/* --- Where the site's own components set Quantico ------------------------------
   The declarations that other components render. Each is a print layer in its
   own right; ink.js measures them with the rest. Sizes under the readability
   floor keep the light type they had, for contrast. */

.glance__name,
.rank__name,
.band-order__price,
.plate-declared__line,
.plate-declared__called,
.slideshow__declaration {
  color: var(--ink-red);
}

/* The great index numerals behind each discipline: red, held back, so they
   stay an index rather than a second headline. */
.discipline__index {
  color: var(--ink-red);
  opacity: 0.6;
}

/* The ghost numeral in the hero is identity artwork, not a declaration: it
   stays a drawn outline and takes no material. */
.hero__numeral {
  -webkit-text-stroke: 1px rgba(220, 34, 39, 0.16);
}

/* Declarations set into photographs carry a little shadow, so red holds on
   whatever the frame is doing beneath the gradient. This is contrast against
   the image, not softness in the letter: the silhouette stays sharp. */
.plate-declared__line,
.plate-declared__called,
.slideshow__declaration {
  text-shadow: 0 1px 18px rgba(0, 0, 0, 0.55);
}
