/* score-grids.css -- HTML score-grid table pages (md/html-score-grids-plan.md).
   Section-by-section rationale: score-grids/styles/score-grids-css.md.
   Source of truth: score-grids/styles/score-grids.css; deployed copy: Public/score-grids.css.
   Old SVG wrapper pages keep referencing viewer.css (body.grids) -- separate file, no overlap. */

/* Page -- white background is load-bearing: the win tints are rgba over white,
   matching the SVG's Opacity[a, color] compositing. */
html, body { margin: 0; background: #fff; }

/* Viewer chrome -- ported from viewer.css (nav/peers/steps on graph-native
   gray); table pages skip the --gw/--gh height-budget machinery. */
.viewer {
	position: relative;
	container-type: inline-size;
	--chrome-scale: 1.1;   /* nav/peers font: x the fitted grid font (fit script) */
	max-width: min(1600px, calc(100vw - 2em));
	margin: 0 auto;
	padding: .4em .4em .8em;
	font-family: Verdana, Geneva, Tahoma, sans-serif;
	color: #262626;
}
/* shrink-wrapped so the absolute .step arrows anchor at the table's edge
   (full-width .graph pushed them off-viewport); tracks the fit automatically */
.graph { position: relative; width: fit-content; max-width: 100%; margin: 0 auto; }
/* margin-inline auto: the fit script caps peers (like the navs) at the
   table width and scales its font with the grid; the cqi clamp is the
   no-JS fallback */
.peers { text-align: center; font-size: clamp(0.82rem, 1.4cqi, 1.6rem); color: #555;
	margin-top: .6em; margin-top: .5lh; margin-inline: auto; padding-bottom: .1em; }
.peers b { color: #262626; }
.peers a { color: #575757; text-decoration: none; }
.peers a:hover { color: blue; }
.step { position: absolute; top: 50%; transform: translateY(-50%);
	font-size: 2.4em; line-height: 1; color: #bcbcbc; text-decoration: none; }
.step:hover { color: blue; }
.step.prev { left: -2rem; }
.step.next { right: -2rem; }
/* margin-inline auto: the fit script caps .nav at the table's width, so the
   bars center on the grid column (as production nav tracks the image) */
.nav { display: grid; grid-template-columns: 1fr auto 1fr; align-items: baseline;
	column-gap: 1em; margin-top: .55em; margin-inline: auto;
	font-size: clamp(0.82rem, 1.4cqi, 1.6rem); }
.nav .nleft { text-align: left; }
.nav .ncenter { text-align: center; font-size: 1em; }
.nav .nright { text-align: right; }
.nav:not(.top) { align-items: start; }
.nav a { color: #262626; text-decoration: none; }
.nav a:hover { color: blue; }
.nav.top { margin-top: 0; margin-bottom: .35em; }
/* No .ncenter override for the top bar any more: it carries the season-table
   back-link where team-history published one.  Where it did not, the empty
   auto track collapses to zero and the corner links keep their places -- so
   the slot is left in flow rather than display:none'd, which would re-place
   the right corner into the centre column. */
body.grids .nav .nleft a + a, body.grids .nav .nright a + a { margin-left: .9em; }
.nav, .peers { -webkit-user-select: none; user-select: none; }

@media (max-width: 640px) {
	.step { display: none; }
	.nav { grid-template-columns: 1fr; row-gap: .25em; }
	.nav .nleft, .nav .ncenter, .nav .nright { text-align: center; }
	/* stacked bars: a centreless header would keep a zero-height row and
	   its two gaps.  Safe to drop here only because the template is a
	   single column -- see score-grids-css.md ("Viewer chrome"). */
	.nav .ncenter:empty { display: none; }
}

/* Scroll wrapper -- both-axis scroll, the sticky containing block and the
   tooltip clip context.  The static max-height is the no-JS fallback only:
   the fit script overrides it every fit (fitted grids get table height +
   escape slack, floor-size grids get the height budget). */
.gridwrap {
	overflow: auto;
	max-height: calc(100vh - 8em);
	max-height: calc(100dvh - 8em);
}

/* Table core -- em-driven sizing (--cell) so the stage-3 fit script scales
   everything through one font size.  border-collapse stays "separate":
   collapsed borders do not follow position:sticky cells. */
table.grid {
	border-collapse: separate;
	border-spacing: 0;
	margin: 0 auto;
	font-family: Helvetica, Arial, sans-serif;
	color: #000;
	font-size: 12px;
	--cell: 2.6em;
	--fit-max: 1.666; /* fit ceiling: x this font size, read by the fit script */
}
table.grid.wide { --cell: 3.0em; }   /* >9-goal seasons: wider score branch */
table.grid th, table.grid td { box-sizing: border-box; font-weight: normal; }

/* Name-column pin -- measured once at load by the emitted script, then
   frozen, so no engine re-derives the width from the names in view during
   scroll (cases/2026-08-01-name-column-scroll-jitter.md).  No JS: auto. */
table.grid.namew th.home, table.grid.namew th.corner {
	width: var(--name-w);
	min-width: var(--name-w);
	max-width: var(--name-w);
}

/* Result ladder -- GENERATED from ScoreGrid.wl initGridStyle/initGridHelpers
   (see score-grids-css.md for the formulas and regeneration).  Do not
   hand-tune; the emitter clamps gd > 13 (home) / |gd| > 9 (away) to the top
   rung.  Classes sit on the result td, or on each stacked line (div) in a
   multi-fixture cell. */
.h1 { background-color: rgba(26,26,255,0.3333); }
.h2 { background-color: rgba(26,26,255,0.4167); }
.h3 { background-color: rgba(26,26,255,0.5000); }
.h4 { background-color: rgba(26,26,255,0.5833); }
.h5 { background-color: rgba(26,26,255,0.6667); }
.h6 { background-color: rgba(26,26,255,0.7500); }
.h7 { background-color: rgba(26,26,255,0.8083); }
.h8 { background-color: rgba(26,26,255,0.8417); }
.h9 { background-color: rgba(26,26,255,0.8750); }
.h10 { background-color: rgba(26,26,255,0.9083); }
.h11 { background-color: rgba(26,26,255,0.9417); }
.h12 { background-color: rgba(26,26,255,0.9750); }
.h13 { background-color: rgba(26,26,255,1.0000); }
.a1 { background-color: rgba(255,0,0,0.3333); }
.a2 { background-color: rgba(255,0,0,0.4167); }
.a3 { background-color: rgba(255,0,0,0.5000); }
.a4 { background-color: rgba(255,0,0,0.5833); }
.a5 { background-color: rgba(255,0,0,0.6667); }
.a6 { background-color: rgba(255,0,0,0.7500); }
.a7 { background-color: rgba(255,0,0,0.8333); }
.a8 { background-color: rgba(255,0,0,0.9167); }
.a9 { background-color: rgba(255,0,0,1.0000); }
.d { background-color: #cccccc; }
.u { background-color: #e8e8e8; }

/* Content cells -- square via the one --cell knob; ruling = right+bottom
   borders (#555, the SVG frame color); the top edge comes from the sticky
   header row's border and the left edge from the sticky name column's, so
   the ruling travels with the freeze. */
td.c {
	width: var(--cell);
	min-width: var(--cell);
	height: var(--cell);
	text-align: center;
	border-right: 1px solid #555;
	border-bottom: 1px solid #555;
	white-space: nowrap;
	padding: 0 2px;
}

/* Unplayed-cell dates -- zero-padded MM-DD, fixed-width mono at 8/9 of the
   score font (7/9 inside stacks), as in the SVG. */
td.c.u, td.c.m div.u {
	color: #0d0d0d;
	font-family: "Courier New", Courier, monospace;
	font-size: 0.889em;
}

/* Stacked-grid cells -- every populated cell is a stack of uniform line
   areas (score or date band), each exactly half the square, top-aligned in
   chronological order: empty space collects at the bottom.  A 2-stack fills
   the square; taller stacks grow the row; singles show one band + white. */
td.c.m { padding: 0; vertical-align: top; }
td.c.m div {
	height: calc(var(--cell) / 2);
	line-height: calc(var(--cell) / 2);
	padding: 0 2px;
}
/* stacked dates run at 7/9 font; --cell is an em token, so dividing the
   height by the same 0.778 re-normalizes it to the table's em -- the band
   stays exactly half the square.  0.778 must track this font-size. */
td.c.m div.u {
	font-size: 0.778em;
	height: calc(var(--cell) / 2 / 0.778);
	line-height: calc(var(--cell) / 2 / 0.778);
}

/* PSO cells -- fill = regulation result (draw gray), inset ring = shootout
   winner's color (team-history's fixwall2 legacy-pso look; box-shadow, not
   border, so the grid ruling stays untouched; em so it scales with the fit). */
.ph { box-shadow: inset 0 0 0 0.25em rgba(26,26,255,0.5); }
.pa { box-shadow: inset 0 0 0 0.25em rgba(255,0,0,0.5); }

/* Sticky axes -- gate-proven 2026-08-01 (rotated+sticky prototype): opaque
   backgrounds on every sticky cell, z ladder corner > header row > name
   column, frozen edges carry their own border. */
table.grid thead th {
	position: sticky;
	top: 0;
	z-index: 3;
	background: #fff;
}
th.away {
	width: var(--cell);
	min-width: var(--cell);
	vertical-align: bottom;
	border-bottom: 1px solid #555;
	line-height: 0;              /* no line-box slack around the inline-block */
	padding: 0;
}
div.vertical {
	white-space: nowrap;
	writing-mode: vertical-rl;
	transform: rotate(-180deg);
	padding: 4px 0;
	/* inline-block, NOT block: WebKit mis-places orthogonal-flow block
	   children of a table cell (sheets-css.md) */
	display: inline-block;
	vertical-align: bottom;
	line-height: normal;
	text-align: left;            /* names start just above the matrix */
}
th.home {
	position: sticky;
	left: 0;
	z-index: 2;
	background: #fff;
	text-align: right;
	padding: 0 6px;
	border-right: 1px solid #555;
	white-space: nowrap;
}

/* Team-page links (pilot): plain-text look, hover blue like the nav */
th.home a, th.away a { color: inherit; text-decoration: none; }
th.home a:hover, th.away a:hover { color: blue; }
/* no border-right: it drew a stray separator up through the header zone
   (the SVG frames the content block only; the vertical ruling comes from
   the body rows' th.home borders).  The z-index needs the full selector:
   a bare th.corner loses the specificity race against the base sticky
   rule above, leaving the corner at z 3 -- away headers then paint over
   it in DOM order while scrolling.  7 = always wins, above the hovered
   name ths (6/4) too. */
th.corner {
	left: 0;
	vertical-align: bottom;
	text-align: right;
	padding: 4px 6px;
}
table.grid thead th.corner { z-index: 7; }

/* Corner box + status block -- SVG parity: rounded gray title box (bold,
   10/9 of the score font), plain status lines under it.  .corner-stack
   shrink-wraps to the wider of the two, so the narrower part centers
   against it (the stack hugs the cell's right edge via the th's
   text-align); status lines stay internally left-justified. */
.corner-stack {
	display: inline-block;
	text-align: center;
}
.corner-box {
	display: inline-block;
	background: rgba(128,128,128,0.1500);
	border-radius: 0.4em;
	padding: .3em .5em;
	font-weight: bold;
	font-size: 1.111em;
	text-align: center;
	color: #000;
}
th.corner .status {
	width: fit-content;
	margin: .35em auto 0;
	text-align: left;
	line-height: 1.3;
	color: #000;
}

/* Stat columns (Home + Total blocks) and the away tfoot -- the SVG's empty
   separator column becomes .b's padding; numbers centered as in the SVG. */
td.s, th.s { text-align: center; padding: 0 .35em; white-space: nowrap; }
.s.b { padding-left: 1.2em; }
thead th.s { vertical-align: bottom; padding-bottom: 2px; }
tfoot tr:first-child th, tfoot tr:first-child td { padding-top: .8em; }
th.home.foot { border-right: none; }

/* Stat-block labels -- "Home"/"Total" over the column triples, rotated
   "Away" left of the tfoot row labels (an addition over the SVG).
   Absolute overlays hosted inside sticky cells: no extra thead row or
   tfoot column, so nothing outside the stat blocks moves and each label
   rides its host cell's freeze (see score-grids-css.md). */
.bh {
	position: absolute;
	bottom: 1.6em;
	left: 50%;
	transform: translateX(-50%);
	font-weight: bold;
}
/* the host GF-GA th must outrank its later Pts sibling, whose opaque
   background would otherwise paint over the label's right half */
table.grid thead th:has(.bh) { z-index: 4; }
/* padding-left reserves the label strip: short name columns must not
   collide label and row labels.  -300%/400% = exactly the four content
   lines (rows 2-4 are one line high like the host; row 1's extra .8em
   is separator padding above its content).  right = padding (6px) +
   the row labels' width (constant strings, all ~1.45em) + the same
   ~0.25em gap the top labels keep above the column headers. */
th.home.foot { padding-left: 1.8em; }
.bv {
	position: absolute;
	right: calc(6px + 1.7em);
	top: -300%;
	height: 400%;
	display: flex;
	align-items: center;
	font-weight: bold;
}

/* Tap/hover tooltips (all devices) -- ported from fixwall2.css
   ("Tap/hover tooltips"), adapted to the grid (see score-grids-css.md):
   carriers = content tds, stacked band divs, name headers; sticky ths are
   already positioned (position:relative would KILL sticky -- do not add
   them to the relative rule); .gridwrap is the clip context. */

/* core: every device.  td.s included ahead of need: stat cells carry no
   tooltip content yet, but may later. */
table.grid td.c:is([title],[data-title]),
table.grid td.s:is([title],[data-title]),
table.grid td.c.m div:is([title],[data-title]) { position: relative; }

/* a hovered name th must outrank its sibling sticky ths: equal z-index
   contexts paint in DOM order, so later rows' opaque name cells would
   cover the bubble hanging down from an earlier row (stays under the
   corner's z 7) */
th.home:is([title],[data-title]):hover { z-index: 4; }

/* the bubble box is shared; content source per attribute */
table.grid [title]:hover::after { content: attr(title); }
table.grid [data-title]:hover::after { content: attr(data-title); }
/* square corners by deliberate deviation from the fixwall bubble's 5px
   radius (third review round) */
table.grid :is([title],[data-title]):hover::after {
	position: absolute;
	top: 100%; right: auto; left: 0;
	z-index: 200;
	pointer-events: none;
	background: rgba(32,32,32,0.95);
	color: #fff;
	box-shadow: 1px 2px 6px rgba(0,0,0,0.4);
	padding: 6px 9px;
	/* bubble text = the row-header names' size: --tipf is the fitted
	   table font, pinned by the fit script (an em would shrink with the
	   8/9 and 7/9 date carriers); 13px = no-JS fallback */
	font: normal var(--tipf, 13px)/1.45 -apple-system, "Segoe UI", sans-serif;
	text-align: left;
	white-space: pre-wrap;
	width: max-content;
	max-width: 320px;
}

/* leftward flip: last six content columns (6 stat cells follow them, so
   content position k-from-right = nth-last-child(6+k)); stacked cells
   flip by the parent td's position */
table.grid td.c:nth-last-child(-n+12):is([title],[data-title]):hover::after,
table.grid td.c.m:nth-last-child(-n+12) div:is([title],[data-title]):hover::after {
	right: 0; left: auto;
}

/* name bubbles (the existing full-name ones, shortened displays only):
   directly below the name, bubble top-RIGHT corner snapped to the name
   cell's bottom-right (third review round) */
table.grid :is(th.home,th.away):is([title],[data-title]):hover::after {
	right: 0; left: auto;
}
/* home-name bubbles wrap within the pinned column width: right-snapped,
   anything wider would poke left out of the wrap and clip */
table.grid th.home:is([title],[data-title]):hover::after {
	max-width: var(--name-w, 320px);
	box-sizing: border-box;
}
/* no z boost for hovered away ths: at the base z their leftward bubble
   already paints above earlier siblings (DOM order) and the name column,
   and the corner must always win (z 7) -- a first-column bubble sliding
   under the corner is the accepted trade */

/* NO hover rule here may touch the box model: .step is absolute at
   top:50% of .graph, so anything that resizes .gridwrap re-centres the
   chevrons under the pointer.  The bottom-row clip escape that used to
   sit here (hover-armed padding-bottom/margin-bottom pair) did exactly
   that -- see score-grids-css.md ("Tap/hover tooltips"). */

/* touch extras, duplicated under both gates -- keep in sync */
@media (any-pointer: coarse) {
	table.grid { touch-action: manipulation; }
	table.grid :is([title],[data-title]) {
		-webkit-tap-highlight-color: transparent;
		-webkit-user-select: none;
		user-select: none;
	}
	/* linked cells navigate on tap: bubble is hover-device-only */
	table.grid :is([title],[data-title]):has(a):hover::after { content: none; }
	/* owner mark on tapped name headers (content cells get the pressed
	   selection instead); no z-index: cells slide under the frozen axes */
	table.grid th:is([title],[data-title]):not(:has(a)):hover {
		outline: 2px dotted black;
		outline-offset: -2px;
	}
}
/* -- second gate: same content as above, keep in sync -- */
@supports (-webkit-touch-callout: none) {
	table.grid { touch-action: manipulation; }
	table.grid :is([title],[data-title]) {
		-webkit-tap-highlight-color: transparent;
		-webkit-user-select: none;
		user-select: none;
	}
	/* linked cells navigate on tap: bubble is hover-device-only */
	table.grid :is([title],[data-title]):has(a):hover::after { content: none; }
	/* owner mark on tapped name headers (content cells get the pressed
	   selection instead); no z-index: cells slide under the frozen axes */
	table.grid th:is([title],[data-title]):not(:has(a)):hover {
		outline: 2px dotted black;
		outline-offset: -2px;
	}
}

/* Hover echo -- the emitted echo script toggles .echo on headers
   (light gray background only: bold would change the pinned name-column
   width).  Scope (block-label round): every cell echoes the thead th at
   its cellIndex + its row's leading th -- content cell -> both name
   headers; stat cell -> the respective name header AND its own stat
   row/column header (tfoot row labels are th.home, so only th.s needs
   adding here).  A hovered stat cell also marks itself with the dotted
   inside border (squad-history hover mark; outline so nothing shifts).
   Tap = hover on touch devices. */
/* name headers gray as whole cells; stat headers gray as a snug chip
   on their .hd span -- the th itself spans the whole thead height /
   name-column width and would gray far beyond the header text.  The
   box-shadow halo pads the chip without touching layout. */
th.home.echo:not(.foot), th.away.echo { background: #d9d9d9; }
.echo .hd { background: #d9d9d9; box-shadow: 0 0 0 2px #d9d9d9; }
tbody td.s:hover, tfoot td.s:hover {
	outline: 1px dotted black;
	outline-offset: -1px;
}

/* Selected cell -- pressed-button inset shadow (the team-history
   fixture-cell hover look).  In a stacked grid the band under the
   pointer is the selection unit (matching per-band tooltips); the empty
   remainder of a stacked cell presses as a whole cell, cancelled while
   a band owns the hover (:has). */
td.c:hover { box-shadow: inset 2px 2px 2px 2px rgba(0,0,0,0.5); }
td.c.m:hover:has(div:hover) { box-shadow: none; }
td.c.m div:hover { box-shadow: inset 2px 2px 2px 2px rgba(0,0,0,0.5); }
/* pso cells: ring + pressed stack (a bare hover shadow would replace the
   ring; keep the ring values in sync with the PSO section) */
td.c.ph:hover, td.c.m div.ph:hover {
	box-shadow: inset 2px 2px 2px 2px rgba(0,0,0,0.5),
		inset 0 0 0 0.25em rgba(26,26,255,0.5);
}
td.c.pa:hover, td.c.m div.pa:hover {
	box-shadow: inset 2px 2px 2px 2px rgba(0,0,0,0.5),
		inset 0 0 0 0.25em rgba(255,0,0,0.5);
}

/* Fit with floor (script emitted per page): table font =
   clamp(9px floor, 12px x min(availW/w, availH/h), 40px), re-fit on
   orientation flips only (desktop window resizes leave the fitted size
   alone; the wrap scrolls instead), --name-w re-measured after every fit;
   the script also owns the .gridwrap height cap and the .nav width caps.
   Everything above is em-driven so this one knob scales the whole grid.
   Calibrated vs the SVG pages 2026-08-02 (48px reserve; see
   score-grids-css.md). */
