/* ============================================================================
   Battlefield board: weathered pale stone against cropped lawn.

   Shared by the Chess Coach board (.chess-wrap.th-field .sq) and the Daily
   Puzzles board (#dcpBoard .dcp-sq), so the look only has to be maintained
   once. Everything ships inside this stylesheet: nothing to download, and it
   stays sharp at any board size instead of blurring like a fixed-resolution
   tile.

   Texture only, by design. No bevels, no sheen, no sunlit patches: the grain
   and the blades carry it on their own, and every square sits flat.

   Two rules learned the hard way and worth keeping:
     - `radial-gradient(circle N% ...)` is INVALID. `circle` takes a length, not
       a percentage; only `ellipse` takes two percentages. One bad layer voids
       the whole background-image declaration silently, with no console error.
     - Two crossed repeating-gradients always read as plaid, never as texture.
       Break the pattern with a third layer at non-harmonic angle AND period.

   Square colors come from --sq-light / --sq-dark where the host page defines
   them (Chess Coach drives those from its theme table), falling back to the
   Battlefield constants on pages that have no theme picker.
   ========================================================================= */

/* Per-square texture offset, applied by the bf-v* classes the boards add as
   they render. Without it every square would show the identical crop of the
   pattern, and 32 identical stones read as wallpaper rather than as rock. */
.chess-wrap.th-field .sq,
#dcpBoard .dcp-sq,
#rycBoard .ryc-sq {
  --bf-ox: 0px;  --bf-oy: 0px;
  /* the river: a channel of water round every square. Drawn as four background
     layers rather than a border, outline or box-shadow, because all three of
     those are already spoken for on one board or the other (selection outlines,
     last-move and hint tints) and a background layer collides with nothing and
     changes no layout. Neighbouring squares each contribute their own width, so
     the channels between squares read twice the bank at the board's edge, which
     is what a river between fields looks like.

     The width is proportional, not fixed, because both boards are fluid: a
     square runs about 97px at the desktop max and about 35px in the narrowest
     column. One pinned value cannot serve both. 2px is thin at 97px and about
     right at 35px, and by 5px the 10px channel between squares swallows a third
     of a small field and the board reads as a blue grid. 3.2% holds the same
     look at every size (about 3px on a desktop square), and the 2px floor keeps
     the line crisp rather than letting it fall to a soft sub-pixel smear on the
     smallest boards. Percentages resolve against the square's own box here, so
     the vertical and horizontal layers come out equal. For a flat value again,
     drop the max() and set a plain length. */
  --bf-river: #4a8cb8;
  --bf-river-w: max(2px, 3.2%);
}
.chess-wrap.th-field .sq.bf-v1,
#dcpBoard .dcp-sq.bf-v1,
#rycBoard .ryc-sq.bf-v1 { --bf-ox: 37px; --bf-oy: 61px; }
.chess-wrap.th-field .sq.bf-v2,
#dcpBoard .dcp-sq.bf-v2,
#rycBoard .ryc-sq.bf-v2 { --bf-ox: 83px; --bf-oy: 19px; }
.chess-wrap.th-field .sq.bf-v3,
#dcpBoard .dcp-sq.bf-v3,
#rycBoard .ryc-sq.bf-v3 { --bf-ox: 19px; --bf-oy: 97px; }

/* ---------------------------------------------------------------- stone ---
   Grain is SVG fractal noise as a data URI, not tiled dot gradients. Dot tiles
   read as a perforated grid at any size, because every tile puts its dot in
   the same place. feTurbulence gives genuinely irregular grain, and
   stitchTiles keeps it seamless where the 140px pattern repeats.             */
.chess-wrap.th-field .sq.light,
#dcpBoard .dcp-sq.light,
#rycBoard .ryc-sq.light {
  background-color: var(--sq-light, #e7e1d4);   /* keep in step with THEMES.field in chess.qmd */
  background-image:
    linear-gradient(to bottom, var(--bf-river) 0 var(--bf-river-w), transparent var(--bf-river-w)),
    linear-gradient(to right,  var(--bf-river) 0 var(--bf-river-w), transparent var(--bf-river-w)),
    linear-gradient(to top,    var(--bf-river) 0 var(--bf-river-w), transparent var(--bf-river-w)),
    linear-gradient(to left,   var(--bf-river) 0 var(--bf-river-w), transparent var(--bf-river-w)),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='bfn'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23bfn)' opacity='0.34'/%3E%3C/svg%3E");
  background-size: auto, auto, auto, auto, 140px 140px;
  background-position: 0 0, 0 0, 0 0, 0 0, var(--bf-ox) var(--bf-oy);
}

/* ---------------------------------------------------------------- grass ---
   Three blade layers at close but non-harmonic angles and periods. Two alone
   would settle into a visible lattice; the third breaks it up.               */
.chess-wrap.th-field .sq.dark,
#dcpBoard .dcp-sq.dark,
#rycBoard .ryc-sq.dark {
  background-color: var(--sq-dark, #5c7d40);
  background-image:
    linear-gradient(to bottom, var(--bf-river) 0 var(--bf-river-w), transparent var(--bf-river-w)),
    linear-gradient(to right,  var(--bf-river) 0 var(--bf-river-w), transparent var(--bf-river-w)),
    linear-gradient(to top,    var(--bf-river) 0 var(--bf-river-w), transparent var(--bf-river-w)),
    linear-gradient(to left,   var(--bf-river) 0 var(--bf-river-w), transparent var(--bf-river-w)),
    repeating-linear-gradient(88deg, rgba(216,240,170,.15) 0 1px, transparent 1px 3px),
    repeating-linear-gradient(97deg, rgba(18,40,12,.17) 0 1px, transparent 1px 7px),
    repeating-linear-gradient(91deg, rgba(24,50,16,.10) 0 2px, transparent 2px 11px);
  background-position:
    0 0, 0 0, 0 0, 0 0,
    var(--bf-ox) var(--bf-oy), var(--bf-ox) var(--bf-oy), var(--bf-ox) var(--bf-oy);
}
