/*
 * MWPP Class Schedule — Dojo skin (Phase T3).
 *
 * THEME_SPEC §2.2: the new default. Keeps v1's sticker DNA (solid category
 * fill, dark border, offset shadow) but designed — warm paper canvas, a
 * real 8px spacing scale, quieter chrome so category color does the
 * talking, and Barlow (regular width) body text instead of Classic's
 * condensed Barlow, which is v1's strongest "built, not designed" tell.
 *
 * D1 OWNERSHIP CONTRACT: every rule here is appearance only, scoped under
 * .mwpp-theme-dojo. No grid mechanics, no float-layer positioning, no
 * behavior-state WIRING, no print scaffolding — those all belong to
 * mwpp-schedule.css and are untouched by this file. This skin defines its
 * OWN token vocabulary (--mwpp-canvas, --mwpp-ink, ...), not Classic's
 * (--mwpp-dark, --mwpp-olive, ...) — the two skins never load together,
 * so there is no naming collision to avoid; reusing Classic's names for
 * different colors (e.g. a --mwpp-dark that isn't dark) would only be
 * confusing to read later. See CLAUDE.md T3 notes for the reasoning.
 */

/* ===================================================== 1. @font-face */

@font-face {
	font-family: 'Bebas Neue';
	font-style: normal;
	font-weight: 400;
	font-display: swap;
	src: url('../../fonts/bebas-neue-400.woff2') format('woff2');
}

@font-face {
	font-family: 'Barlow';
	font-style: normal;
	font-weight: 400;
	font-display: swap;
	src: url('../../fonts/barlow-400.woff2') format('woff2');
}

@font-face {
	font-family: 'Barlow';
	font-style: normal;
	font-weight: 600;
	font-display: swap;
	src: url('../../fonts/barlow-600.woff2') format('woff2');
}

/* ===================================================== 2. design tokens */

.mwpp-theme-dojo {
	--mwpp-canvas: #F6F5F1;
	--mwpp-ink: #21211E;
	--mwpp-deep: #26261F;
	--mwpp-olive: #8F9678;
	--mwpp-green: #6F9671;
	--mwpp-hairline: #DCDAD2;
	--mwpp-muted: #6F6F68;

	/* Card border color at 90% opacity, per THEME_SPEC's "tightened to
	   3px/0-blur at 90% Ink opacity" — a literal rgba, since plain CSS
	   cannot derive an alpha variant of a hex custom property. */
	--mwpp-shadow-color: rgba(33, 33, 30, 0.9);

	--mwpp-font-display: 'Bebas Neue', 'Arial Narrow', sans-serif;
	--mwpp-font-body: 'Barlow', 'Helvetica Neue', Arial, sans-serif;

	/* An 8px spacing scale — every gap/padding/margin below is one of
	   these six values, never an arbitrary pixel figure (THEME_SPEC's
	   "professional standard" requirement). */
	--mwpp-space-1: 8px;
	--mwpp-space-2: 16px;
	--mwpp-space-3: 24px;
	--mwpp-space-4: 32px;
	--mwpp-space-5: 40px;
	--mwpp-space-6: 48px;

	--mwpp-card-radius: 10px;
	--mwpp-card-border-w: 1.5px;
	--mwpp-card-shadow: 3px 3px 0 0 var(--mwpp-shadow-color);
	--mwpp-card-shadow-hover: 5px 5px 0 0 var(--mwpp-shadow-color);
	--mwpp-card-lift: -2px;

	/* Hover grow (v1.4.1): Dojo MIRRORS Classic's scale-on-hover exactly
	   (parity was Mike's explicit call after the chip and absolute-expansion
	   mechanisms were both rejected in LocalWP). Same factor as Classic's
	   --mwpp-sticker-hover-scale so the two themes behave identically. */
	--mwpp-sticker-hover-scale: 1.5;

	/* Hover name outline (v1.4.1): the hover-revealed full name is white on
	   the card's own category fill, and several seeded fills pair weakly with
	   white — measured WCAG, white vs fill: specialty #FF8C00 2.33:1,
	   youth-gi #959D7A 2.84:1, openmat #17A2B8 3.04:1, youth-nogi #709671
	   3.34:1, adult-gi #888888 3.54:1 (all under AA 4.5:1). scale(1.5) makes
	   that text the focal point of the page, so the weakness is magnified.
	   A crisp 1px Ink outline fixes it because Ink is INVERSELY correlated
	   with white across the same palette (6.92 / 5.67 / 5.30 / 4.83 / 4.55:1
	   on those same five fills) and only fades where white is already ~8:1
	   (striking 8.45:1, adult-nogi 8.25:1). At every one of the 8 fills at
	   least one edge clears AA — worst case adult-gi, 4.55:1 — and the
	   outline separates from its own white fill at 16.14:1, so the letterform
	   edge is always defined. A blurred glow was rejected: it spreads the same
	   dark mass at low alpha and greys the counters of 0.95rem/600 Barlow
	   instead of defining them, washing out on exactly the light fills that
	   need the help.
	   THIS IS A PER-THEME TOKEN HOLDING THE WHOLE text-shadow VALUE, not just
	   a colour — when this hover treatment rolls out to Nightfall, Daybreak
	   and Kraft, each supplies its OWN value, and a dark theme can supply a
	   soft light GLOW here without needing a different rule shape. Never
	   hardcode this into core or a shared rule.

	   THE OUTLINE COLOUR FOLLOWS THE CARD'S OWN TEXT COLOUR, and that is not a
	   Dojo constant: MWPP_Renderer::text_color_for() computes it PER CATEGORY
	   from that category's fill luminance, so a light fill yields DARK text
	   (#2b2b2b) and a dark fill yields white. The figures above are the
	   white-text case. On a DARK-text card a fixed dark ink is the same colour
	   as the text (#21211E vs #2b2b2b = 1.14:1) and the name turns to mud —
	   which is exactly what happened once a lighter palette was applied (four
	   of the eight categories in Nightfall's suggested palette flip to dark
	   text, including both youth greens). The seed palette hid this because
	   every seed fill happens to yield white text.
	   --mwpp-cat-contrast is the renderer's own answer: whichever of the two
	   text constants text_color_for() did NOT pick, emitted per card. Reading
	   it here makes ONE rule adapt per card with no branching. The
	   var(--mwpp-ink) fallback is load-bearing, not decoration — a category
	   whose colour the renderer could not resolve (or any hand-built or
	   third-party card that never gets the property) degrades to exactly the
	   pre-v1.4.1 dark-ink outline rather than to an invalid text-shadow.
	   HONEST NOTE FOR ANY RETUNE: on a dark-text card the light outline is
	   damage-stop plus edge definition (12.98:1 against the letterform), NOT a
	   contrast rescue — that text already measures 7.4-8.6:1 on its own fill.
	   It reads as a soft halo, not the crisp ring white text gets. If it ever
	   looks like a smudge, `text-shadow: none` for the dark-text case is a
	   defensible one-value change; the token shape supports either.

	   *** --mwpp-name-outline IS DECLARED ON .mwpp-card, NOT HERE, AND THAT IS
	   LOAD-BEARING — DO NOT "TIDY" IT BACK INTO THIS BLOCK. *** A custom
	   property's var()s are substituted at COMPUTED-VALUE TIME ON THE ELEMENT
	   THE DECLARATION APPLIES TO, and the resolved value is what inherits.
	   Declared here (on .mwpp-page.mwpp-theme-dojo) --mwpp-cat-contrast is not
	   in scope, so every card would inherit the ALREADY-SUBSTITUTED ink
	   fallback and the adaptation would silently never happen — measured, not
	   assumed: in that shape both a dark-text and a light-text card computed
	   the identical #21211E outline. The renderer sets --mwpp-cat-contrast on
	   .mwpp-card[data-category], so the token must be declared at or below the
	   card for the substitution to see it. See section 5. */

	--mwpp-badge-radius: 3px;

	/* Badge hover fade (v1.4.1): on hover the mat badge dims so the enlarged
	   name is the focus. The badge still carries real information (WHICH MAT),
	   so this is "de-emphasised", never "dimmed to uselessness" — the value is
	   measured, not picked by eye.
	   opacity renders the badge (background AND text) into a buffer and then
	   composites that buffer over the card fill, so BOTH converge toward the
	   fill and the badge's own internal contrast collapses as opacity drops.
	   Worst case across all 16 fills of the seed + Nightfall palettes, badge
	   text vs badge background:
	       0.50 -> 3.41:1   0.55 -> 3.95:1   0.60 -> 4.58:1
	       0.65 -> 5.34:1   0.70 -> 6.22:1   1.00 -> 14.80:1
	   AA for this text (0.625rem semibold, 15px once the card is scaled) is
	   4.5:1, so 0.50 — the value originally suggested — is genuinely below the
	   bar on the light Nightfall greens. 0.60 is the lowest value that clears
	   AA, but only by 0.08 and on a palette-dependent fill (NF openmat), so a
	   slightly lighter palette would drop it under with nobody watching. 0.65
	   keeps real headroom (5.34:1) for a fade difference that is imperceptible
	   next to 0.60 — Mike's call after reviewing 0.50/0.60/0.65 side by side.
	   The badge also stays readable AS A CHIP against the card (badge
	   background vs fill 1.60:1 at 0.60, 1.65:1 at 0.65, 1.91:1 at full).
	   UNLIKE --mwpp-name-outline, THIS TOKEN BELONGS IN THIS ROOT BLOCK and is
	   safe here: it is a plain number referencing no renderer-emitted per-card
	   property, so the custom-property substitution trap documented on that
	   token does not apply. Do NOT "fix" it onto .mwpp-card by analogy. */
	--mwpp-badge-hover-opacity: 0.65;

	--mwpp-panel-radius: 12px;
	--mwpp-footer-radius: 8px;
	--mwpp-overlay-radius: 6px;

	--mwpp-pill-radius: 999px;
	--mwpp-dot-size: 10px;

	--mwpp-logo-size: 108px;
	--mwpp-logo-size-mobile: 88px;
	--mwpp-logo-radius: 12px;
	--mwpp-logo-shadow: 0 2px 8px rgba(33, 33, 30, 0.15);

	--mwpp-eyebrow-size: 12px;
	--mwpp-eyebrow-size-mobile: 11px;
	--mwpp-eyebrow-weight: 600;
	--mwpp-eyebrow-tracking: 0.3em;
	--mwpp-title-tracking: 0.01em;
	--mwpp-title-line-height: 0.95;
	--mwpp-title-size-mobile: 2rem;
}

/* ===================================================== 3. header / legend / notes */

.mwpp-theme-dojo .mwpp-header {
	gap: var(--mwpp-space-3);
	padding-bottom: var(--mwpp-space-3);
	margin-bottom: var(--mwpp-space-3);
	/* "A single 1px Hairline rule runs under the entire header" — the
	   masthead treatment that replaces Classic's three boxed panels. */
	border-bottom: 1px solid var(--mwpp-hairline);
}

.mwpp-theme-dojo .mwpp-brand {
	gap: var(--mwpp-space-2);
}

/* BRANDING: SPECIFICITY IS LOAD-BEARING HERE, NOT COSMETIC — same doctrine
 * as themes/classic.css section 3 (the 0.1.7 branding fix, carried forward
 * per THEME_SPEC §7.2's "0.1.7 theme-collision rule carries over
 * unchanged"). The renderer emits the title as an <h2> and the logo as an
 * <img>; a WP theme (Kadence on the reference site) styles those with
 * descendant selectors like `.entry-content h2` / `.entry-content img`
 * (0,1,1). Every rule below is scoped `.mwpp-theme-dojo {context}
 * element.class` (0,3,1) to clear that, and each one explicitly RESETS
 * the properties a theme is likely to set even where we would not
 * otherwise mention them. Do not "simplify" these selectors back to a
 * single class. */
.mwpp-theme-dojo .mwpp-brand img.mwpp-logo,
.mwpp-theme-dojo .mwpp-mobile-header img.mwpp-logo {
	width: var(--mwpp-logo-size);
	height: var(--mwpp-logo-size);
	max-width: none; /* beats the theme's img { max-width: 100% } */
	border-radius: var(--mwpp-logo-radius);
	background: var(--mwpp-canvas);
	box-shadow: var(--mwpp-logo-shadow);
	object-fit: contain; /* contain, never cover — a logo is artwork, not a crop target */
	display: block;
	margin: 0;
	padding: 0;
	border: 1px solid var(--mwpp-hairline);
	flex-shrink: 0;
}

.mwpp-theme-dojo .mwpp-brand .mwpp-eyebrow,
.mwpp-theme-dojo .mwpp-mobile-header .mwpp-eyebrow {
	font-family: var(--mwpp-font-body);
	font-size: var(--mwpp-eyebrow-size);
	font-weight: var(--mwpp-eyebrow-weight);
	text-transform: uppercase;
	letter-spacing: var(--mwpp-eyebrow-tracking);
	line-height: 1.2;
	color: var(--mwpp-green);
	margin: 0 0 4px;
	padding: 0;
}

.mwpp-theme-dojo .mwpp-brand h2.mwpp-title,
.mwpp-theme-dojo .mwpp-mobile-header h2.mwpp-title {
	font-family: var(--mwpp-font-display);
	font-weight: 400;
	/* POST-T3 FIX (CLAUDE.md "ISSUE 3", header height pass): ceiling raised
	   from 3.25rem back to 3.5rem (56px), same as Classic — at real desktop
	   widths 52px read noticeably smaller than Classic and made the header
	   feel uncertain rather than authoritative, per Mike's call after
	   seeing both live. Same clamp discipline as 0.1.7/Classic otherwise:
	   reaches the ceiling by ~1366px and holds flat above that (verified in
	   a real browser down to 993px — no header overflow at any width in
	   between), never only at the widest viewports, while still shrinking
	   gracefully toward the 993px breakpoint. */
	font-size: clamp(1.75rem, 0.5rem + 3.6vw, 3.5rem);
	line-height: var(--mwpp-title-line-height);
	letter-spacing: var(--mwpp-title-tracking);
	color: var(--mwpp-ink);
	/* Bebas Neue's glyphs are already uppercase by design (see CLAUDE.md's
	   "TITLE CASE / BEBAS NEUE" section) — do not add text-transform:
	   uppercase, and do not remove this explicit `none` reset, which is
	   what beats a theme forcing uppercase on headings. */
	text-transform: none;
	margin: 0.15em 0 0;
	padding: 0;
}

.mwpp-theme-dojo .mwpp-header .mwpp-legend,
.mwpp-theme-dojo .mwpp-header .mwpp-notes {
	border-radius: var(--mwpp-panel-radius);
	padding: var(--mwpp-space-2) var(--mwpp-space-3);
}

/* POST-T3 FIX (CLAUDE.md "ISSUE 2/3", header height pass): legend and notes
   no longer share one flex-basis/max-width. Now that the legend's row count
   is fixed by grid-template-columns below (not a function of its own
   width), it doesn't need the 320px core default (.mwpp-header .mwpp-legend,
   .mwpp-header .mwpp-notes { flex: 1 1 200px; min-width: 0; }) to stay
   compact — it can afford to run narrower, freeing width for notes. Notes
   gets BOTH the freed width (max-width raised to 400px) and a heavier
   flex-grow (1.3 vs the core default's 1) so it actually reaches toward
   that cap instead of settling for whatever's left over: Dojo's notes use
   the non-condensed Barlow body face (a deliberate T3 design choice, see
   this file's own docblock), which wraps real sentences at a narrower
   column than Classic's condensed font ever does at the same width — this
   was misread as the notes panel "stretching to fill the header" when it
   was actually genuinely sizing to wrapped content in too narrow a column.
   Verified in a real browser: this alone took notes from 236-290px down to
   218-290px depending on width, without moving anything else. */
.mwpp-theme-dojo .mwpp-header .mwpp-legend {
	flex: 0 1 300px;
	max-width: 300px;
}

.mwpp-theme-dojo .mwpp-header .mwpp-notes {
	flex: 1.3 1 280px;
	max-width: 400px;
}

.mwpp-theme-dojo .mwpp-legend {
	background: var(--mwpp-canvas);
	border: 1px solid var(--mwpp-hairline);
	color: var(--mwpp-ink);
}

.mwpp-theme-dojo .mwpp-notes {
	/* The one dark element on the page — anchors the header without
	   Classic's heavier "boxed panel" weight (no border needed; the fill
	   itself reads as a panel against the Canvas page). */
	background: var(--mwpp-deep);
	color: var(--mwpp-canvas);
}

.mwpp-theme-dojo .mwpp-legend h3,
.mwpp-theme-dojo .mwpp-notes h3 {
	font-family: var(--mwpp-font-display);
	font-weight: 400;
	font-size: 1.125rem;
	letter-spacing: 0.01em;
	margin: 0 0 var(--mwpp-space-1);
}

.mwpp-theme-dojo .mwpp-legend h3 {
	color: var(--mwpp-ink);
}

.mwpp-theme-dojo .mwpp-notes h3 {
	color: var(--mwpp-olive);
}

/* POST-T3 FIX (CLAUDE.md "ISSUE 1", header height pass): fixed 3-column
   grid, not the flex-wrap row of pills this replaced. flex-wrap made row
   count a function of the legend panel's own width — worse exactly when
   the header could least afford it (6 rows at 1200px vs 4 at 1920px,
   measured before this fix) — where a FIXED column count makes row count a
   function of the category COUNT only (8 categories / 3 columns = 3 rows,
   flat from 1920px down to 1366px, verified in a real browser). Same
   row-count-determinism mechanism Classic's two-column dot-list grid
   already relies on, just one column denser here since Dojo's pill chrome
   needs the extra column to land on a comparable total height. */
.mwpp-theme-dojo .mwpp-legend-grid {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 6px 8px;
}

.mwpp-theme-dojo .mwpp-legend-item {
	display: flex;
	align-items: center;
	gap: 4px;
	font-family: var(--mwpp-font-body);
	font-weight: 600;
	/* Tightened from 0.8125rem/5px 12px to fit three per row cleanly at the
	   legend's new, narrower 300px cap (see .mwpp-header .mwpp-legend
	   above) — reads a shade smaller than before, a deliberate trade Mike
	   accepted for the flatter row count. */
	font-size: 0.71875rem;
	background: var(--mwpp-canvas);
	border: 1px solid var(--mwpp-hairline);
	border-radius: var(--mwpp-pill-radius);
	padding: 4px 6px;
	cursor: pointer;
	text-align: left;
	color: var(--mwpp-ink);
	transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}

.mwpp-theme-dojo .mwpp-legend-item:focus-visible,
.mwpp-theme-dojo .mwpp-time-header button:focus-visible {
	outline: 2px solid var(--mwpp-green);
	outline-offset: 2px;
}

.mwpp-theme-dojo .mwpp-legend-dot {
	width: var(--mwpp-dot-size);
	height: var(--mwpp-dot-size);
	min-width: var(--mwpp-dot-size);
	border-radius: 50%;
	background: var(--mwpp-olive);
	display: inline-block;
}

/* The olive fill above is a fallback only. The per-instance <style> block
   emitted by MWPP_Renderer adds one small selector rule per category
   actually used — .mwpp-legend-item[data-category="{key}"] .mwpp-legend-dot
   { background: var(--mwpp-cat-{key}); } — since plain CSS cannot turn a
   data-attribute value into a custom-property name. */

.mwpp-theme-dojo .mwpp-notes ul {
	list-style: none;
	margin: 0;
	padding: 0;
	font-family: var(--mwpp-font-body);
	font-weight: 400;
	font-size: 0.9375rem;
}

.mwpp-theme-dojo .mwpp-notes li {
	padding: var(--mwpp-space-1) 0;
	border-top: 1px dashed rgba(246, 245, 241, 0.18);
}

.mwpp-theme-dojo .mwpp-notes li:first-child {
	border-top: none;
}

.mwpp-theme-dojo .mwpp-hover-hint {
	opacity: 0.7;
	font-style: italic;
}

/* ===================================================== 4. table + cells */

.mwpp-theme-dojo .mwpp-schedule-wrap {
	border-radius: var(--mwpp-panel-radius);
	border: 1px solid var(--mwpp-hairline);
	background: var(--mwpp-canvas);
}

.mwpp-theme-dojo .mwpp-schedule {
	background: var(--mwpp-hairline);
}

.mwpp-theme-dojo .mwpp-schedule thead th {
	background: var(--mwpp-ink);
	color: var(--mwpp-canvas);
	font-family: var(--mwpp-font-body);
	font-weight: 600;
	font-size: 0.875rem;
	letter-spacing: 0.12em;
	text-transform: uppercase;
}

.mwpp-theme-dojo .mwpp-show-times .mwpp-time-header {
	background: var(--mwpp-deep);
	color: var(--mwpp-canvas);
}

.mwpp-theme-dojo .mwpp-time-cell {
	background: var(--mwpp-canvas);
	font-family: var(--mwpp-font-body);
	text-align: left;
	vertical-align: middle;
	padding: 0 var(--mwpp-space-1);
	color: var(--mwpp-ink);
}

.mwpp-theme-dojo .mwpp-time-start {
	display: block;
	font-weight: 600;
	font-size: 0.9375rem;
}

.mwpp-theme-dojo .mwpp-time-range {
	display: block;
	font-family: var(--mwpp-font-body);
	font-weight: 400;
	font-size: 0.6875rem;
	color: var(--mwpp-muted);
}

.mwpp-theme-dojo .mwpp-day-cell {
	background: var(--mwpp-canvas);
}

.mwpp-theme-dojo .mwpp-spacer-row {
	/* CLAUDE.md "ISSUE 3": same var(--mwpp-spacer-color, var(--mwpp-olive))
	   fallback chain as themes/classic.css — an unset/uncustomized
	   schedule falls through to Dojo's own --mwpp-olive (#8F9678). */
	background: var(--mwpp-spacer-color, var(--mwpp-olive));
	/* Covers the table's own border-spacing gap below the last row —
	   same seam fix as themes/classic.css (see its own comment for the
	   full CSS2.1 §17.5.2.1 explanation); tied to the same core geometry
	   var so it can never drift out of sync, and to the same color var as
	   `background` above so a customized spacer_color covers the seam in
	   its own color. */
	box-shadow: 0 var(--mwpp-cell-gap) 0 0 var(--mwpp-spacer-color, var(--mwpp-olive));
}

/* ===================================================== 5. cards */

.mwpp-theme-dojo .mwpp-card {
	/* The actual design height — under the core's structural
	   max-height:var(--mwpp-row-h) ceiling. Never min-height (see the
	   core's comment on why that reopens the row-height bug). */
	height: var(--mwpp-card-h);
	border-radius: var(--mwpp-card-radius);
	border: var(--mwpp-card-border-w) solid var(--mwpp-ink);
	box-shadow: var(--mwpp-card-shadow);
	background: var(--mwpp-olive);
	color: var(--mwpp-ink);
	text-align: center;
	padding: var(--mwpp-space-1);
	transition: transform 0.2s ease, box-shadow 0.2s ease, z-index 0s;

	/* The hover name outline (see section 2 for the contrast measurements and
	   the full rationale). DECLARED HERE, on the card, ON PURPOSE: this is the
	   nearest element at which the renderer's per-card --mwpp-cat-contrast is
	   in scope, and a custom property's var()s resolve against the element the
	   declaration applies to — not against the element that later uses the
	   token. Declaring it in section 2's root token block computes the ink
	   fallback once, up there, and inherits that fixed value to every card, so
	   the outline would never adapt (verified in a real browser, not reasoned
	   about: both a dark-text and a light-text card came back with the same
	   #21211E). Declared here it computes PER CARD, which is the whole fix.
	   Setting it at rest costs nothing — nothing consumes it until :hover. */
	--mwpp-name-outline:
		 1px 0 0 var(--mwpp-cat-contrast, var(--mwpp-ink)), -1px 0 0 var(--mwpp-cat-contrast, var(--mwpp-ink)),
		 0 1px 0 var(--mwpp-cat-contrast, var(--mwpp-ink)), 0 -1px 0 var(--mwpp-cat-contrast, var(--mwpp-ink)),
		 1px 1px 0 var(--mwpp-cat-contrast, var(--mwpp-ink)), -1px 1px 0 var(--mwpp-cat-contrast, var(--mwpp-ink)),
		 1px -1px 0 var(--mwpp-cat-contrast, var(--mwpp-ink)), -1px -1px 0 var(--mwpp-cat-contrast, var(--mwpp-ink));
}

/* The olive/ink fill above is a fallback only (the only case it should
   ever apply is a dangling type reference). The per-instance <style>
   block adds one selector rule per category actually used — see
   MWPP_Renderer::render_style_block(). */

.mwpp-theme-dojo .mwpp-mat-badge {
	/* Small top-left pill, not Classic's small centered text. */
	position: absolute;
	top: 6px;
	left: 6px;
	transform: none;
	font-family: var(--mwpp-font-body);
	font-weight: 600;
	font-size: 0.625rem;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	background: var(--mwpp-ink);
	color: var(--mwpp-canvas);
	border-radius: var(--mwpp-badge-radius);
	padding: 2px 6px;

	/* Matches the card's own `transform 0.2s ease` exactly (see
	   .mwpp-theme-dojo .mwpp-card) so the badge fades WHILE the card grows
	   rather than snapping partway through. Declared at rest, not on :hover,
	   because a transition must exist on the element in BOTH directions for
	   the fade back in on mouse-out to animate too. */
	transition: opacity 0.2s ease;
}

.mwpp-theme-dojo .mwpp-name-abbr {
	font-family: var(--mwpp-font-body);
	font-weight: 600;
	font-size: 1.1rem;
	line-height: 1.2;
}

.mwpp-theme-dojo .mwpp-name-full,
.mwpp-theme-dojo .mwpp-time-line {
	font-family: var(--mwpp-font-body);
	line-height: 1.2;
}

.mwpp-theme-dojo .mwpp-name-full {
	font-weight: 600;
	font-size: 0.95rem;
}

/* 0.625rem = 10px, reduced from 0.75rem/12px in v1.4.3 — see the same note in
   themes/classic.css. MEASURED benefit here is the largest of the three by
   card count: at 1277 the number of cards whose name+time stack overflows the
   content box halves, 14 -> 7, and 9px/8px hold at 7 (the knee is 10px).
   WHAT THIS DOES NOT FIX, recorded so it is not re-attempted: Dojo's 4-line
   hover names are 8/41 at EVERY candidate size, worst overflow 30px -> 28px.
   Those names are ~73px tall in a ~67px content box, so the name alone exceeds
   the box before the time is counted and no time reduction can resolve it.
   Mike reviewed that state and called it acceptable. */
.mwpp-theme-dojo .mwpp-time-line {
	font-weight: 400;
	font-size: 0.625rem;
	margin-top: 0.2rem;
}

@media (min-width: 993px) {
	/* Hover: MIRROR Classic exactly — uniform transform: scale() grow-in-place.
	   The card enlarges from its own position (no reflow: a transform never
	   affects layout flow), the core swaps abbr -> full so the full name shows
	   inside the scaled card, and the core .mwpp-card:hover{z-index:20} (plus the
	   JS bindHoverZ inline z:20) lifts it above neighbours — all shared with
	   Classic, unchanged. Uniform scale is inherently CONSISTENT card-to-card,
	   which is the point: the earlier absolute-expansion mechanism flickered and
	   varied per card, and Mike rejected it for exactly that. If scale(1.5) does
	   not fully contain the longest dual-mat name in a narrow cell, that is
	   Classic's accepted behaviour and Dojo inherits it — do not "fix" it.
	   Classic also sets `width: var(--mwpp-sticker-hover-width)` (230px) here,
	   but it is INERT on a flex:1 1 0 card (flex-basis:0 overrides width — Classic
	   measures ~110px = 1.5x, not 230px), so it is deliberately OMITTED here
	   rather than carried over as a dead declaration. Do not add it back. */
	.mwpp-theme-dojo .mwpp-card:hover {
		transform: scale(var(--mwpp-sticker-hover-scale));
		box-shadow: var(--mwpp-card-shadow-hover);
	}

	/* FIX 1 (v1.4.1) — badge z-order, HOVER ONLY. The mat badge is
	   position:absolute (see .mwpp-theme-dojo .mwpp-mat-badge above) with no
	   z-index, and .mwpp-name-full is a static in-flow flex child, also with
	   no z-index. Per CSS 2.1 painting order a positioned descendant with
	   z-index:auto (step 8) paints ABOVE in-flow static content (steps 4-7)
	   regardless of DOM order — so the badge covered the name unconditionally.
	   That is a painting-order fact, not a z-index contest: there was no
	   number to out-bid, which is why only promoting the name to a POSITIONED
	   element fixes it. Measured at 1024px: 39 of the 41 badge-bearing desktop
	   cards had the badge overlapping the name (up to 54x24px), with
	   elementFromPoint at the overlap returning .mwpp-mat-badge.
	   position:relative carries NO offsets, so this is z-order only and shifts
	   nothing. Scoped to :hover deliberately — at REST the badge stays on top,
	   which is the intended resting look and stays byte-identical.
	   NOT applied to .mwpp-time-line: measured across all 41 badge-bearing
	   cards, the time line never overlaps the badge (0 of 41; minimum vertical
	   gap from badge bottom to time top is 24px), so promoting it would be
	   dead weight. If a future skin change moves the badge or the time line,
	   re-measure before assuming that still holds. */
	.mwpp-theme-dojo .mwpp-card:hover .mwpp-name-full {
		position: relative;
		z-index: 1;
	}

	/* FIX 2 (v1.4.1) — name legibility, HOVER ONLY. See --mwpp-name-outline
	   in section 2 for the contrast measurements and why a crisp Ink outline
	   beats a glow on this palette. text-shadow is paint-only: it never
	   affects layout, so this cannot reflow or resize anything.
	   Hover-only by design. The same white-on-fill weakness exists at rest,
	   but rest is small abbr text on its own card rather than the magnified
	   focal point, and outlining every resting card would change Dojo's
	   resting appearance — which this pass deliberately leaves byte-identical.
	   Applied to the NAME only, never .mwpp-time-line. */
	.mwpp-theme-dojo .mwpp-card:hover .mwpp-name-full {
		text-shadow: var(--mwpp-name-outline);
	}

	/* FIX 3 (v1.4.1) — badge hover fade. De-emphasises the mat badge while the
	   name is enlarged. See --mwpp-badge-hover-opacity in section 2 for the
	   measured contrast basis for the value.
	   THIS IS ADDITIONAL TO FIX 1, NOT A REPLACEMENT FOR IT: the name still
	   paints ABOVE the badge (z-index:1 above the badge's auto). Note that
	   opacity < 1 makes the badge a STACKING CONTEXT — it still paints at the
	   z-index:0 position within the card, so the name's z-index:1 continues to
	   win, but that is verified in a real browser (verify-dojo-hover item 10's
	   elementFromPoint check) rather than assumed from the spec.
	   opacity is paint-only: it cannot move or resize anything. */
	.mwpp-theme-dojo .mwpp-card:hover .mwpp-mat-badge {
		opacity: var(--mwpp-badge-hover-opacity);
	}
}

/* Motion, not appearance: under prefers-reduced-motion the hover treatment must
   reach the SAME end state instantly instead of animating to it. The badge fade
   is new in v1.4.1, but the card's own scale transition has been unguarded since
   the Classic mirror landed — a real accessibility gap. Closing BOTH here is a
   DELIBERATE change to the approved scale mechanism (Mike's explicit call: "it's
   a real accessibility gap, it's one line, this is the cheapest moment to close
   it"), not an accidental side effect of the badge work. End states are
   identical either way: the card still scales, the badge still fades — they just
   arrive immediately. */
@media (prefers-reduced-motion: reduce) {
	.mwpp-theme-dojo .mwpp-card,
	.mwpp-theme-dojo .mwpp-mat-badge {
		transition: none;
	}
}

/* ---------------------------------------- badge reserve (v1.4.2, measured) */
/* Drops the RESTING three-line name clear of the mat badge. Core declares the
   mechanism on .mwpp-name-abbr and defaults it to 0px (D5 define-don't-apply);
   this is the only place Dojo opts in, and the value is this skin's own.
   ONE VALUE CANNOT SERVE ALL FOUR BADGE THEMES — they build their badges three
   different ways and it lands at a different height in each (measured badge
   bottom, from the card's top edge: dojo 23px, nightfall 23px, daybreak 24px,
   kraft 37-40px), so the required drop is 6/4/4/14px respectively. Classic
   already clears at +1.4px and sets nothing.

   THE UPPER BOUND IS MEASURED, NOT ROUNDED: 2100px is the widest viewport at
   which Dojo still has a glyph-under-badge collision. Above it there is
   nothing to correct and the token must not apply, so the width every theme was
   approved at (2560px) stays byte-identical. Like Kraft's 1415/1365 and its
   1161 ladder, this literal is tied to THIS schedule's class names and this
   skin's card width — it is NOT a universal constant and must be re-measured if
   either changes. */
@media (min-width: 993px) and (max-width: 2100px) {
	.mwpp-theme-dojo .mwpp-name-abbr {
		--mwpp-badge-reserve: 6px;
	}
}

/* ===================================================== 6. mobile (<= breakpoint) */

@media (max-width: 992px) {
	.mwpp-theme-dojo .mwpp-mobile-header {
		gap: var(--mwpp-space-1);
		text-align: center;
		margin-bottom: var(--mwpp-space-2);
	}

	/* Same specificity-parity requirement as Classic's mobile block: must
	   carry at least the specificity of the branding rules in section 3
	   (0,3,1), or those would outrank them. */
	.mwpp-theme-dojo .mwpp-mobile-header img.mwpp-logo-mobile {
		width: var(--mwpp-logo-size-mobile);
		height: var(--mwpp-logo-size-mobile);
	}

	.mwpp-theme-dojo .mwpp-mobile-header .mwpp-eyebrow {
		font-size: var(--mwpp-eyebrow-size-mobile);
	}

	.mwpp-theme-dojo .mwpp-mobile-header h2.mwpp-title {
		font-size: var(--mwpp-title-size-mobile);
	}

	.mwpp-theme-dojo .mwpp-mobile-notes {
		background: var(--mwpp-deep);
		color: var(--mwpp-canvas);
		border-radius: var(--mwpp-panel-radius);
		padding: var(--mwpp-space-2) var(--mwpp-space-3);
		margin-bottom: var(--mwpp-space-2);
		text-align: center;
	}

	.mwpp-theme-dojo .mwpp-mobile-notes h3 {
		font-family: var(--mwpp-font-display);
		font-weight: 400;
		color: var(--mwpp-olive);
		margin: 0 0 var(--mwpp-space-1);
	}

	.mwpp-theme-dojo .mwpp-mobile-notes ul {
		list-style: none;
		margin: 0;
		padding: 0;
		font-family: var(--mwpp-font-body);
		font-size: 0.9375rem;
	}

	.mwpp-theme-dojo .mwpp-mobile-notes li {
		padding: 6px 0;
	}

	.mwpp-theme-dojo .mwpp-legend-hint {
		background: var(--mwpp-ink);
		color: var(--mwpp-canvas);
		font-family: var(--mwpp-font-body);
		font-weight: 600;
		font-size: 0.8125rem;
		letter-spacing: 0.08em;
		text-transform: uppercase;
		text-align: center;
		padding: var(--mwpp-space-1);
		border-radius: 6px;
		margin-bottom: var(--mwpp-space-2);
	}

	/* MONO POLISH PASS (issue 6), REVERSING A T3 DECISION: this was a single
	   column of full-width pills at T3 build time (per the THEME_SPEC
	   mobile note, "same pill style as desktop but full-width on mobile"),
	   which read as a deliberate design choice against Classic's own
	   viewport-dependent `repeat(auto-fit, minmax(200px,1fr))`. Measured
	   in a real browser at a 390px viewport: with only 8 legend items, one
	   per row consumed noticeably more vertical space than necessary before
	   the mat headers/schedule even start, and Classic doesn't actually
	   reach 2 columns at that width either (auto-fit needs >=400px) — so
	   "match Classic" wasn't really the baseline in practice. Switched to a
	   fixed 2-column grid (reliable at any width, unlike Classic's
	   auto-fit) per Mike's explicit request. display:grid itself is still
	   the core's switching mechanic (base state is display:none); this
	   skin only supplies the column pattern, per the D1 "legend pattern"
	   boundary. */
	.mwpp-theme-dojo .mwpp-mobile-legend {
		grid-template-columns: repeat(2, 1fr);
		gap: var(--mwpp-space-1);
		margin-bottom: var(--mwpp-space-3);
	}

	.mwpp-theme-dojo .mwpp-mobile-legend .mwpp-legend-item {
		border: 1px solid var(--mwpp-hairline);
		border-radius: var(--mwpp-pill-radius);
		padding: 10px 16px;
		justify-content: flex-start;
		background: var(--mwpp-canvas);
	}

	.mwpp-theme-dojo .mwpp-mobile-mat-headers {
		margin-bottom: var(--mwpp-space-1);
	}

	.mwpp-theme-dojo .mwpp-mobile-mat-header {
		/* Slightly lighter than Ink, per THEME_SPEC mobile note. */
		background: #3A3A34;
		color: var(--mwpp-canvas);
		font-family: var(--mwpp-font-body);
		font-weight: 600;
		font-size: 0.75rem;
		letter-spacing: 0.08em;
		text-transform: uppercase;
		text-align: center;
		padding: 8px;
		border-radius: 6px;
	}

	.mwpp-theme-dojo .mwpp-mobile-day-header {
		/* Barlow 600, matching the desktop day-header band treatment —
		   THEME_SPEC's mobile note calls for the same Ink/light/Barlow 600
		   treatment here, not Classic's Bebas mobile day header. */
		background: var(--mwpp-ink);
		color: var(--mwpp-canvas);
		font-family: var(--mwpp-font-body);
		font-weight: 600;
		font-size: 0.9375rem;
		letter-spacing: 0.1em;
		text-transform: uppercase;
		text-align: center;
		padding: 10px;
		border-radius: 6px;
		margin: var(--mwpp-space-2) 0 var(--mwpp-space-1);
	}

	.mwpp-theme-dojo .mwpp-mobile-day-header:first-of-type {
		margin-top: 0;
	}

	.mwpp-theme-dojo .mwpp-mobile-schedule .mwpp-card {
		padding: var(--mwpp-space-2);
	}

	.mwpp-theme-dojo .mwpp-mobile-schedule .mwpp-name-full {
		font-size: 1.05rem;
	}

	.mwpp-theme-dojo .mwpp-footer-note {
		text-align: center;
	}
}

/* ===================================================== 7. footer note */

.mwpp-theme-dojo .mwpp-footer-note {
	background: var(--mwpp-canvas);
	border: 1px solid var(--mwpp-hairline);
	border-radius: var(--mwpp-footer-radius);
	padding: 10px var(--mwpp-space-2);
	margin-top: var(--mwpp-space-2);
	font-size: 0.85rem;
	color: var(--mwpp-ink);
}

/* ===================================================== 8. filter states */

/* The .mwpp-filtering/.mwpp-match/.mwpp-dim dim/highlight/wiggle mechanic
   itself lives in the structural core (Phase T1 post-gate fix — see
   CLAUDE.md) with a universal working baseline. This theme overrides the
   legend .mwpp-dim opacity per THEME_SPEC's explicit Behavior States list
   (0.35, not core's 0.3) — a deliberate, theme-specific value, not an
   oversight if it reads differently from Classic. */
.mwpp-theme-dojo .mwpp-legend-item.mwpp-dim {
	opacity: 0.35;
}

/* Active legend pill: Ink fill, Canvas text — the dot itself keeps its
   category color via the higher-specificity data-category rule in the
   per-instance <style> block, so it never inherits this text color. */
.mwpp-theme-dojo .mwpp-legend-item[aria-pressed="true"] {
	background: var(--mwpp-ink);
	color: var(--mwpp-canvas);
	border-color: var(--mwpp-ink);
}

.mwpp-theme-dojo .mwpp-mobile-legend .mwpp-legend-item[aria-pressed="true"] {
	background: var(--mwpp-ink);
	color: var(--mwpp-canvas);
	border-color: var(--mwpp-ink);
}

/* ===================================================== 9. time-toggle appearance */

.mwpp-theme-dojo .mwpp-slot-time-overlay {
	padding: 4px 6px;
	background: var(--mwpp-ink);
	color: var(--mwpp-canvas);
	font-family: var(--mwpp-font-body);
	font-weight: 600;
	font-size: 0.6875rem;
	line-height: 1.2;
	text-align: center;
	border-radius: 0 0 var(--mwpp-overlay-radius) var(--mwpp-overlay-radius);
}

/* ===================================================== 10. print */

@media print {
	.mwpp-theme-dojo .mwpp-card:hover {
		transform: none !important;
		width: auto !important; /* mirrors Classic's print reset; harmless (hover sets no width) */
		box-shadow: var(--mwpp-card-shadow) !important;
	}

	/* Defensive, same posture as the width reset above: :hover cannot be
	   active while printing, so the v1.4.1 hover outline is already inert
	   here — this just guarantees no dark halo can reach paper if a print
	   preview ever resolves a hover state. */
	.mwpp-theme-dojo .mwpp-card:hover .mwpp-name-full {
		text-shadow: none !important;
	}

	/* Same defensive posture again: the mat badge prints at FULL strength. The
	   hover fade is already inert on paper (:hover cannot be active while
	   printing), but a faded badge would lose the mat information the printed
	   schedule exists to carry, so this is guaranteed rather than assumed. */
	.mwpp-theme-dojo .mwpp-card:hover .mwpp-mat-badge {
		opacity: 1 !important;
	}

	/* No dark panels in print, per THEME_SPEC: Notes renders with a
	   Hairline border on Canvas instead of the Deep background — category
	   fills on the cards themselves are untouched and still print. */
	.mwpp-theme-dojo .mwpp-notes {
		background: var(--mwpp-canvas) !important;
		color: var(--mwpp-ink) !important;
		border: 1px solid var(--mwpp-hairline) !important;
	}

	.mwpp-theme-dojo .mwpp-notes h3 {
		color: var(--mwpp-ink) !important;
	}

	.mwpp-theme-dojo .mwpp-notes li {
		border-top-color: var(--mwpp-hairline) !important;
	}
}
