/* ============================================================================
   TRIUMPH DESIGN SYSTEM v2 — pattern.css
   The interlocking-T woven "Pattern" element, done correctly.

   REWRITTEN 2026-08-18 to match tokens.css and SKILL.md. The previous version
   still shipped the old engine: two seamless PNG tiles (triumph-pattern-fog.png
   and triumph-pattern-navy.png) repeated at a 3:4 background-size and rotated
   -8deg. tokens.css dropped --brand-pattern-white and --brand-pattern-navy when
   it moved to the vector tile, so every class in that file resolved to an
   undefined background and painted NOTHING. If a page linked pattern.css and
   showed no weave, this is why.

   THE CURRENT ENGINE, one idea:
     ONE seamless vector tile (419x279, exactly one repeat period, ~3:2) is
     embedded in tokens.css as --brand-weave and applied as an alpha MASK over a
     flat fill. The fill colour is --brand-pattern-ink, so the same tile recolors
     to any surface instead of needing a file per colourway. Upright, no tilt.

   WHY A MASK AND NOT A BACKGROUND IMAGE:
     - One asset, any colour, any surface. No white-file / navy-file pair to
       keep in sync, and no third file the day a new ground appears.
     - The tile is a true repeat period rebuilt as vector, so it tiles at any
       size with zero seams. Scale is a knob, not a hazard.
     - --brand-weave is a data URI on purpose. A mask loaded from an external
       file gets silently CORS-dropped in some page and path contexts, and the
       weave just vanishes. Same-origin bytes cannot fail that way.

   THE THREE THINGS THAT STILL BREAK IT:
   1. Changing --brand-pattern-size to something that is not ~3:2. The tile is
      419x279. Scale BOTH numbers together or the motif squashes.
   2. Painting the pattern on the global body. It is an opt-in ::before layer
      per band or panel, with the content in a z-index:1 sibling.
   3. transform: rotate() on a repeating layer. The old engine needed the tilt
      to look woven and paid for it with bare corners on short bands. This tile
      does not. Do not reintroduce it.

   SEAN'S STANDING RULE, above this file: the weave NEVER touches a light
   surface, at any opacity, including a whisper watermark. .brand-field-light
   and .brand-watermark stay defined so pages that already reference them keep
   rendering, and they are not to be used in new work. The class existing is
   not an argument.
   ========================================================================== */

/* ---- The layer -----------------------------------------------------------
   Every weave class is this ::before plus a ground colour, an ink, and an
   opacity. Nothing else differs between them. */
.brand-field,
.brand-field--flat,
.brand-field-light,
.brand-field-night,
.brand-zone,
.accent-band,
.brand-watermark {
  position: relative;
  overflow: hidden;
  isolation: isolate;
}
.brand-field > *,
.brand-field--flat > *,
.brand-field-light > *,
.brand-field-night > *,
.brand-zone > *,
.accent-band > *,
.brand-watermark > * { position: relative; z-index: 1; }

.brand-field::before,
.brand-field--flat::before,
.brand-field-light::before,
.brand-field-night::before,
.brand-zone::before,
.accent-band::before,
.brand-watermark::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--brand-pattern-ink);
  -webkit-mask-image: var(--brand-weave);
          mask-image: var(--brand-weave);
  -webkit-mask-repeat: repeat;
          mask-repeat: repeat;
  -webkit-mask-size: var(--brand-pattern-size);
          mask-size: var(--brand-pattern-size);
  -webkit-mask-position: 0 var(--brand-pattern-y, 0);
          mask-position: 0 var(--brand-pattern-y, 0);
  opacity: var(--brand-pattern-opacity, .08);
  pointer-events: none;
  z-index: 0;
}

/* ---- 1. Full-bleed weave field on a navy surface -------------------------
   The default promo ground. Subtle enough to sit behind running text. */
.brand-field,
.brand-field--flat {
  background: var(--navy);
  color: var(--ink-on-navy);
  --brand-pattern-ink: #ffffff;
  --brand-pattern-opacity: .08;
}

/* ---- 2. Accent band / strip ----------------------------------------------
   Fixed-height masthead or footer strip. Louder, because little text sits on
   it, and denser, because the band is short. Scale stays 3:2. */
.accent-band {
  background: var(--navy);
  color: var(--ink-on-navy);
  --brand-pattern-ink: #ffffff;
  --brand-pattern-opacity: .12;
  --brand-pattern-size: 180px 120px;
}

/* ---- 3. Near-black graphic canvas ----------------------------------------
   Deep Night ground. The weave is the graphic here rather than a texture
   behind copy, so the opacity is high on purpose. Poster and cover use only. */
.brand-field-night {
  background: var(--night);
  color: var(--ink-on-navy);
  --brand-pattern-ink: var(--navy);
  --brand-pattern-opacity: .85;
}

/* ---- 4. Page-height zone -------------------------------------------------
   One field behind a whole page rather than a band. Quieter than a field, and
   faded out at the bottom so long copy never fights it. */
.brand-zone {
  background: var(--navy);
  color: var(--ink-on-navy);
  --brand-pattern-ink: #ffffff;
  --brand-pattern-opacity: var(--brand-zone-opacity, .05);
}
/* The fade is a second layer over the weave, NOT a composited mask. A
   two-layer mask needs the legacy -webkit- composite value in Safari and the
   standard one everywhere else, and getting it wrong drops the whole mask and
   paints a solid block. A gradient in the ground colour cannot fail that way. */
.brand-zone::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 45%;
  background: linear-gradient(to bottom, transparent, var(--navy));
  pointer-events: none;
  z-index: 0;
}

/* ---- 5. BANNED on new work: weave on a light surface ---------------------
   Kept defined only so pages that already reference them keep rendering. */
.brand-field-light {
  background: var(--fog);
  color: var(--ink);
  --brand-pattern-ink: var(--navy);
  --brand-pattern-opacity: .07;
}
.brand-watermark {
  --brand-pattern-ink: var(--navy);
  --brand-pattern-opacity: .04;
}

/* ---- Green gradient hero accent rule (the flyer underline) --------------- */
.accent-rule {
  height: 6px;
  width: 120px;
  border: 0;
  background: var(--grad-hero);                  /* lime -> dark green, never flip */
}

/* ---- Continuous field across stacked bands -------------------------------
   A mask starts at each element's own top edge, so two stacked bands restart
   the tile and the rows do not meet. Set --brand-pattern-y per band to the
   negative of its offset down the document, modulo the tile height, and the
   page reads as one uninterrupted field. The screen system ships field.js,
   which writes exactly this. A print piece is one page and rarely needs it. */
