/* Texture options, review only.

   Design constraint, learned the hard way: no repeating orthogonal lattice.
   A background grid almost never lands on the content grid, and the eye reads
   the mismatch as misalignment rather than as texture. Everything here is
   either non-repeating, non-orthogonal, or keyed to the band structure the
   page already has.

   Each layer is a body class so combinations can be compared live. Once a
   direction is chosen, keep the winning rules and delete the rest along with
   the .txpanel markup in build.mjs and the texture block in app.js. */

/* ======================================================= background stock */
/* These belong UNDER the content. A fixed full-viewport overlay draws across
   raised elements too, which ruled hatching straight through the capability
   profile. Each surface carries its own layer behind its own content instead,
   which is also how real stock behaves: the card is a separate sheet lying on
   the page, not printed into it. */
body[class*='tx-'] .band::after,
body[class*='tx-'] .approach::after,
body[class*='tx-'] .window::after {
  content: '';
  position: absolute; inset: 0;
  z-index: 0;
  pointer-events: none;
}

/* --- paper grain ---------------------------------------------------------- */
body.tx-grain .band::after,
body.tx-grain .approach::after,
body.tx-grain .window::after {
  opacity: .11;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.55' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 180px 180px;
}

/* --- security hatch ------------------------------------------------------- */
/* The lining of a tamper-evident envelope. Diagonal, so it never sets up a
   horizontal or vertical rhythm to compete with the columns. */
body.tx-hatch .band::after,
body.tx-hatch .approach::after,
body.tx-hatch .window::after {
  background-image: repeating-linear-gradient(
    58deg, rgba(19, 26, 44, .05) 0 1px, transparent 1px 7px);
}
body.tx-hatch .band-ink::after {
  background-image: repeating-linear-gradient(
    58deg, rgba(255, 255, 255, .055) 0 1px, transparent 1px 7px);
}

/* --- cotton fleck --------------------------------------------------------- */
/* Sparse fibres suspended in the sheet, the way cotton stock looks held to
   the light. Entirely non-repeating at reading distance, so there is no
   rhythm of any kind to misalign. */
body.tx-fleck .band::after,
body.tx-fleck .approach::after,
body.tx-fleck .window::after {
  opacity: .5;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='f'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='1' stitchTiles='stitch'/%3E%3CfeComponentTransfer%3E%3CfeFuncA type='discrete' tableValues='0 0 0 0 0 0 0 0 0 0 0 0 0 0 1'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='300' height='300' filter='url(%23f)' opacity='.5'/%3E%3C/svg%3E");
  background-size: 300px 300px;
}
body.tx-fleck .band-ink::after { opacity: .3; filter: invert(1); }

/* --- survey rings --------------------------------------------------------- */
/* Concentric rings off a point beyond the frame: a radar sweep, or the
   contour of a site plan. Curved, so nothing lines up with a column edge. */
body.tx-rings .band::after,
body.tx-rings .approach::after,
body.tx-rings .window::after {
  background-image: repeating-radial-gradient(
    circle at 92% 18%,
    rgba(19, 26, 44, .045) 0 1px, transparent 1px 58px);
}
body.tx-rings .band-ink::after {
  background-image: repeating-radial-gradient(
    circle at 92% 18%,
    rgba(216, 184, 112, .085) 0 1px, transparent 1px 58px);
}
body.tx-rings .band:nth-of-type(even)::after {
  background-image: repeating-radial-gradient(
    circle at 8% 82%,
    rgba(19, 26, 44, .045) 0 1px, transparent 1px 58px);
}

/* ================================================================== depth */
/* Alternatives to a grid that reinforce the page's alignment instead of
   competing with it, because both key off the band edges that are already
   there. */

/* --- stacked sheets ------------------------------------------------------- */
/* Each band reads as a separate sheet laid on the one beneath: a catch of
   light along its top edge and a soft shadow along its bottom. */
body.tx-sheets .band {
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .9),
    inset 0 -1px 0 rgba(19, 26, 44, .07);
}
body.tx-sheets .band-ink {
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .08),
    inset 0 -1px 0 rgba(0, 0, 0, .3);
}
body.tx-sheets .band::before {
  content: '';
  position: absolute; left: 0; right: 0; top: 0; height: 90px;
  z-index: 0; pointer-events: none;
  background: linear-gradient(180deg, rgba(19, 26, 44, .035), transparent);
}
body.tx-sheets .band-ink::before {
  background: linear-gradient(180deg, rgba(0, 0, 0, .22), transparent);
}

/* --- raking light --------------------------------------------------------- */
/* A low directional wash across each band, alternating side. Pure light, no
   geometry, so there is nothing that can fail to line up. */
body.tx-rake .band::before {
  content: '';
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: linear-gradient(104deg,
    rgba(19, 26, 44, .05) 0%, transparent 42%, rgba(255, 255, 255, .5) 100%);
}
body.tx-rake .band:nth-of-type(even)::before {
  background: linear-gradient(256deg,
    rgba(19, 26, 44, .05) 0%, transparent 42%, rgba(255, 255, 255, .5) 100%);
}
body.tx-rake .band-ink::before {
  background: linear-gradient(104deg,
    rgba(0, 0, 0, .3) 0%, transparent 46%, rgba(216, 184, 112, .07) 100%);
}

/* Content rides above whichever layers are on. */
body[class*='tx-'] .band > .wrap { position: relative; z-index: 1; }
body[class*='tx-'] .card,
body[class*='tx-'] .frames,
body[class*='tx-'] .vow,
body[class*='tx-'] .enter,
body[class*='tx-'] .win-in { z-index: 6; }

/* ================================================================== marks */

/* --- corner reticles ------------------------------------------------------ */
/* The corner bracket from the gate frames, repeated at each band. It sits on
   the content gutter, so it marks the alignment rather than fighting it. */
body.tx-reticle .band > .wrap { position: relative; }
body.tx-reticle .band > .wrap::before,
body.tx-reticle .band > .wrap::after {
  content: '';
  position: absolute;
  width: 22px; height: 22px;
  border: 1px solid var(--gold);
  opacity: .55;
  pointer-events: none;
}
body.tx-reticle .band > .wrap::before {
  left: calc(var(--gutter) - 14px); top: -14px;
  border-right: 0; border-bottom: 0;
}
body.tx-reticle .band > .wrap::after {
  right: calc(var(--gutter) - 14px); bottom: -14px;
  border-left: 0; border-top: 0;
}

/* --- Spartan watermark ---------------------------------------------------- */
/* Tone-on-tone, the business card's spot-UV idea translated. Sized and placed
   to sit fully inside the band: a cropped mark reads as a mistake. */
.sp-watermark { display: none; }
body.tx-spartan .s-contact { overflow: hidden; }
body.tx-spartan .sp-watermark {
  display: block;
  position: absolute;
  right: clamp(16px, 5vw, 76px);
  top: 50%;
  translate: 0 -50%;
  width: clamp(190px, 26vw, 330px);
  aspect-ratio: 1;
  pointer-events: none;
  z-index: 0;
}
.sp-mark { position: absolute; inset: 0; color: #fff; opacity: .07; display: block; }
.sp-mark svg { width: 100%; height: 100%; display: block; }
/* A band of light travelling across the mark as the section passes, so it is
   legible mainly in motion. */
.sp-sheen {
  position: absolute; inset: 0;
  background: linear-gradient(115deg,
    transparent 36%, rgba(216, 184, 112, .55) 50%, transparent 64%);
  background-size: 300% 300%;
  background-position: var(--sheen, 110%) 50%;
  -webkit-mask-image: var(--sp-mask); mask-image: var(--sp-mask);
  -webkit-mask-size: contain; mask-size: contain;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center; mask-position: center;
  opacity: .6;
}

@media (max-width: 1100px) {
  /* The form reflows to one column here, so the mark would sit behind the
     fields. Move it out of the reading path rather than shrinking it. */
  body.tx-spartan .sp-watermark {
    top: auto; bottom: clamp(14px, 4vw, 40px); translate: 0;
    right: clamp(12px, 4vw, 40px);
    width: clamp(150px, 34vw, 240px);
  }
  .sp-mark { opacity: .055; }
}
@media (max-width: 900px) {
  body.tx-reticle .band > .wrap::before { left: calc(var(--gutter) - 10px); }
  body.tx-reticle .band > .wrap::after { right: calc(var(--gutter) - 10px); }
}

/* =========================================================== review panel */
.txpanel {
  position: fixed; left: 14px; bottom: 14px; z-index: 150;
  background: rgba(255, 255, 255, .97);
  border: 1px solid var(--line-2); border-radius: 12px;
  padding: 12px 14px 10px;
  box-shadow: 0 14px 40px rgba(19, 26, 44, .22);
  display: grid; gap: 9px;
  max-height: calc(100svh - 28px); overflow-y: auto;
}
.txpanel[hidden] { display: none; }
.txpanel-h {
  margin: 0;
  font-family: var(--f-display); font-weight: 700; font-size: 10.5px;
  letter-spacing: .2em; text-transform: uppercase; color: var(--gold-deep);
}
.txpanel fieldset { border: 0; padding: 0; margin: 0; display: grid; gap: 4px; }
.txpanel legend {
  padding: 0 0 3px;
  font-family: var(--f-display); font-weight: 600; font-size: 9.5px;
  letter-spacing: .18em; text-transform: uppercase; color: var(--faint);
}
.txpanel label {
  display: flex; align-items: center; gap: 8px;
  font-size: 13px; color: var(--ink); cursor: pointer;
}
.txpanel input { accent-color: var(--gold-deep); width: 14px; height: 14px; }
.txpanel button {
  margin-top: 2px; background: none; border: 0; padding: 4px 0;
  font-family: var(--f-display); font-weight: 600; font-size: 10.5px;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--muted); cursor: pointer; text-align: left;
}
.txpanel button:hover { color: var(--ink); }
