/* Avatarian BLOCK LAYOUT — how the glyphs stack, and nothing else.
 *
 * Split out of style.css because three surfaces have to agree on it:
 * the standalone site, the wiki gadget (wiki/MediaWiki_Common.css.txt,
 * which restates these rules in em so Avatarian scales with the article
 * text), and the glyph designer's live preview, which links this very
 * file so what it shows is the real layout rather than a copy that
 * drifts. Page chrome — the output card, the per-word captions — stays
 * in style.css; only what a block IS lives here.
 *
 * Everything here is driven by js/render.js. Colours come from the
 * host page's variables (--ink, --warn), so this file is theme-agnostic
 * and works in the site and the designer unchanged.
 *
 * A block is a PAIR of phonemes, written top slot then bottom slot (see
 * the header of js/render.js). Blocks pack tight with no borders; word
 * spacing, not per-block borders, separates words.
 *
 * Sizing follows the SOUND, not the slot: consonants are 5 units tall,
 * vowels 4, and the two stack flush with nothing between them. At 52px
 * per consonant that puts a unit at 10.4px, so a vowel is 41.6px —
 * including a vowel sitting in the top slot, which happens whenever a
 * word starts with one ("at", "up").
 *
 * A vowel keeps the FULL block width and loses only height — canon
 * draws vowel marks wide and flat, spanning their partner. It gets that
 * shape from a separately generated flat drawing, NOT by being squashed
 * at render time. Height alone is the ratio; width is not.
 */

.avatarian-word {
  display: inline-flex; align-items: flex-start;
  margin: 6px 30px 10px 0;
}
.avatarian-block {
  display: inline-flex; flex-direction: column; align-items: center;
  margin-right: 3px;
}
.avatarian-slot { display: flex; justify-content: center; }
/* The two glyphs in a block share a lattice edge — a consonant's bottom
   row line IS the vowel's top row line (glyphspec.py: "stack flush, 5
   units over 4"). But each SVG carries its own clearance margin outside
   the lattice (10svg on a 100 box = 5.2px for a consonant, 8svg on an 80
   box = 4.16px for a flat vowel). Stacking the boxes flush would leave
   both margins as a gap, so pull the bottom slot up by their sum to make
   the lattices meet. The 4.5-unit shrink on C+C blocks keeps this sum at
   5.2+4.16 for every common pairing, so one constant covers them. */
.avatarian-slot-bottom { margin-top: calc(var(--av-size) * -0.18); }

/* ONE knob: a consonant's box. Everything else is a ratio off it, so
   the whole thing scales by setting --av-size on any ancestor — which is
   what the output's size control does. The defaults are exactly the
   values that used to be hardcoded (52, 41.6, 46.8, -9.36). */
:root { --av-size: 52px; }

.avatarian-glyph { display: inline-block; line-height: 0; color: var(--ink); }
.avatarian-glyph svg { display: block; width: 100%; height: 100%; }
/* Consonants: 5 units square. Vowels: 4 units tall, full width — 4/5.
   3-row vowels leave the top row of their 4-row viewBox empty (gap);
   4-row vowels fill it (bridge to the consonant above). */
.avatarian-glyph.avatarian-consonant,
.avatarian-glyph.avatarian-null_consonant {
  width: var(--av-size); height: var(--av-size);
}
.avatarian-glyph.avatarian-vowel,
.avatarian-glyph.avatarian-null {
  width: var(--av-size); height: calc(var(--av-size) * 0.8);
}
/* A block of two consonants (B1, settled session 12). Two consonants are
   ten lattice rows of content in a nine-row block, and they resolve it by
   OVERLAPPING one row: the bottom row of the top glyph and the top row of
   the bottom glyph are the same row. Both stay FULL size — no shrink, so
   stroke weight matches the rest of the writing — and the extra row is
   swallowed by the overlap rather than by scaling.

   The pull-up below does it. A consonant box carries 10% clearance top
   and bottom (10svg on a 100 box), so two boxes stacked flush leave a
   0.2-unit gap between their lattices; closing that AND overlapping one
   more lattice row (16svg = 0.16 units) is 0.2 + 0.16 = 0.36. This
   replaces, not adds to, the -0.18 the V-C bottom slot uses.

   render.js tags a two-consonant block `avatarian-cc` (no vowel, no
   null), so this is a plain class rather than a :has() selector — :has()
   isn't in older browsers and MediaWiki's CSS linter rejects it. */
.avatarian-block.avatarian-cc .avatarian-slot-bottom {
  margin-top: calc(var(--av-size) * -0.36);
}

/* A 3-row vowel is drawn BOTTOM-ALIGNED in its 4-row box: ink in the
   lower three rows, top row empty. That is correct in the bottom slot,
   where the empty row is the gap between the consonant above and the
   vowel — but in the TOP slot the same drawing puts that empty row at
   the block's outer edge as dead space, and leaves the vowel sitting
   flush against the consonant with no gap at all.

   The rule is: rows 1-3 vowel, row 4 gap, rows 5-9 consonant. So the
   vowel is pulled up one lattice row when it sits on top, which moves
   the empty row to where it belongs — between the two glyphs. The
   vowel's ink is the only thing that moves; the row it vacates was
   empty, so nothing overflows the block.

   One lattice row is 20% of the box, NOT 25%. The box is not four rows
   tall — a vowel's viewBox is 80 units: 64 of lattice (4 rows x 16) plus
   16 of clearance margin outside it. So a row is 16/80. Using 25% here
   overshot by a quarter of a row and made the V-C gap wider than the
   C-V one when the two should match. Percentage rather than the 8.32px
   it works out to, so it holds at any size.

   4-row vowels are excluded: they fill their box and abut the
   consonant directly, which is already right in either slot. */
.avatarian-slot-top .avatarian-glyph.avatarian-vowel:not(.avatarian-4row),
.avatarian-slot-top .avatarian-glyph.avatarian-null:not(.avatarian-4row) {
  transform: translateY(-20%);
}

/* Bottom-slot glyphs are the same drawing mirrored top-to-bottom. A
   transform rather than a second asset: it is exact, costs nothing, and
   keeps stroke weight and dot roundness identical to the top form.
   This sits on the SVG, the row shift above on the wrapping span, so
   the two compose instead of overwriting each other. */
.avatarian-glyph.avatarian-flipped svg { transform: scaleY(-1); }

/* A 3-row vowel that ALSO flips (æ, ə, aɪ) needs the row shift too, and
   in the bottom slot rather than the top. The drawing is bottom-aligned
   with its empty row on top; mirroring it for the bottom slot moves that
   empty row to the block's outer edge, so the ink floats up toward the
   consonant and the inner gap vanishes — "fire"'s aɪ sat a full row high,
   bar mid-slot instead of on the baseline. Push it back down one lattice
   row, the exact counterpart of the top-slot pull-up above. On the span,
   so it composes with the SVG's scaleY(-1) rather than fighting it. */
.avatarian-slot-bottom .avatarian-glyph.avatarian-vowel.avatarian-flipped:not(.avatarian-4row),
.avatarian-slot-bottom .avatarian-glyph.avatarian-null.avatarian-flipped:not(.avatarian-4row) {
  transform: translateY(20%);
}

/* Vowels carry both a square (100×100) and flat (100×80) SVG; always
   use the flat form. Consonants have only the square one. */
.avatarian-glyph .g-square:not(:only-of-type) { display: none; }

.avatarian-placeholder { opacity: 0.5; }
.avatarian-missing { font-size: 13px; color: var(--warn); line-height: 1; }

/* A glyph that IS in the source but could not be made out. Deliberately
   unlike .avatarian-missing, which means this tool has no drawing yet:
   that is a gap someone can close by drawing a glyph, this one is a gap
   in the reading and only a better look at the source closes it.

   Dimmed rather than coloured as a warning — it is an honest record, not
   an error, and a word full of red marks reads as broken when it is
   simply partly unread. */
/* Punctuation: one lattice column wide, nine rows tall — the height of a
   whole block rather than of a slot, which is why it sits beside the
   writing instead of in it.

   The box is 36x164 units for a one-column mark (52x164 for the wide
   question mark) against a letter's 100x100, scaled by the same
   units-per-pixel so the stroke weight and row pitch match the letters
   beside it. render.js sets each mark's aspect-ratio inline from its own
   viewBox, so only the height is fixed here — a wider mark keeps its true
   proportions instead of a hardcoded default. */
.avatarian-mark {
  display: inline-block; line-height: 0; color: var(--ink);
  align-self: stretch;
  height: calc(var(--av-size) * 1.64);
  flex: none;
}
.avatarian-mark svg { display: block; width: 100%; height: 100%; }

.avatarian-unreadable { opacity: 0.68; }
/* Higher specificity than .avatarian-flipped svg (both are two classes +
   svg) plus later source order, so it wins without !important. */
.avatarian-glyph.avatarian-unreadable svg { transform: none; }
