/* =====================================================================
 * BATAS ExamCenter — the examiner dashboard ([batas_examiner]).
 *
 * READ THIS BEFORE EDITING. The ExamCenter renders INSIDE the theme's
 * `#main` reading sheet, whose element rules are ID-scoped (1,0,1) and
 * therefore outrank any single-class rule this file can write. That is
 * why the block order below is load-bearing:
 *
 *   0 · BREAK OUT   — escape the 860px paper card
 *   1 · DE-THEME    — zero the theme's element margins, once
 *   2 · RE-ASSERT   — restate our own spacing from that zero baseline
 *   3 · BANK HTML   — contain the server-sanitised past-Bar markup
 *   4 · RESETS      — controls, links, the brand lockup
 *   5 · TOKENS      — one palette, one 4px grid, four radii, rem type
 *   6+ · the app
 *
 * MAINTENANCE CONTRACT: any new rule that sets margin/padding on
 * p / ul / ol / li / h1-h4 / blockquote MUST carry the `#main .batas-px`
 * prefix, or the theme silently beats it.
 *
 * Palette: the site is warm forest/cream. There is ONE action colour
 * (forest). Gold means attention and nothing else. No web-blue.
 * =================================================================== */

/* ═════════════════════════════════════════════════════════════════════
 * 0 · BREAK OUT — this is an application, not a page.
 *
 * Written TWICE in adjacent but SEPARATE blocks, never comma-joined: a
 * selector list is atomic, so one unsupported `:has()` compound would
 * discard the whole rule. The body-class form (stamped by
 * Batas_Proctor::body_class) parses everywhere and comes first; the
 * `:has()` twin is a belt on top. Both are (1,2,0) and beat
 * `body.batas-app #main` (1,1,0) without depending on print order.
 *
 * 1120px matches the theme's other app surfaces (catalog, dashboard,
 * account) and the site header/footer `.wrap` — a wider app would
 * visibly out-dent the brand bar and read as a bug.
 * ═══════════════════════════════════════════════════════════════════ */
body.batas-app.batas-px-page #main {
	max-width: 1120px;
	margin: 1.5rem auto 2.5rem;
	padding: 0 1.5rem;
	background: none;
	border: 0;
	border-radius: 0;
	box-shadow: none;
}
body.batas-app #main:has(.batas-px) {
	max-width: 1120px;
	margin: 1.5rem auto 2.5rem;
	padding: 0 1.5rem;
	background: none;
	border: 0;
	border-radius: 0;
	box-shadow: none;
}

/* The theme ships no page.php, so a Page falls through to index.php,
   which always prints `<h2><a>ExamCenter</a></h2>` above .entry-content
   — the same word the rail lockup and the app bar already say. The app
   emits a real <h1> in its top bar, so this is pure duplication.
   Removed from the document rather than sr-only'd: keeping it would
   make the outline read h2 → h1. */
body.batas-px-page #main > article > h2 { display: none; }
#main:has(.batas-px) > article > h2 { display: none; }

/* The theme re-applies the paper card at ≤640px from a list this
   surface is also absent from. Mirror the pair inside that breakpoint. */
@media (max-width: 640px) {
	body.batas-app.batas-px-page #main { margin: 0 0 1.5rem; padding: 0 12px; border-radius: 0; }
}
@media (max-width: 640px) {
	body.batas-app #main:has(.batas-px) { margin: 0 0 1.5rem; padding: 0 12px; border-radius: 0; }
}

/* `#site-header` is sticky at top:0; WordPress's admin bar is fixed and
   pushes `html { margin-top: 32px }`, so for every professor who is
   also an editor the header's top 32px hide underneath it. */
body.batas-px-page #site-header { top: var(--wp-admin--admin-bar--height, 0px); }

/* ═════════════════════════════════════════════════════════════════════
 * 1 · DE-THEME — zero the theme's element box model, once.
 * `#main p { margin: 0 0 1.1rem }` and friends are (1,0,1); every
 * component rule here would otherwise lose regardless of load order.
 * NOTE: li padding is deliberately NOT zeroed — .px-a-opts li needs it.
 * ═══════════════════════════════════════════════════════════════════ */
#main .batas-px :is(h1, h2, h3, h4, p, blockquote, hr, figure, dl, dd, fieldset) { margin: 0; }
#main .batas-px :is(ul, ol) { margin: 0; padding: 0; }
#main .batas-px li { margin: 0; }
#main .batas-px fieldset { padding: 0; border: 0; }

/* ═════════════════════════════════════════════════════════════════════
 * 2 · RE-ASSERT — our own spacing, from that zero baseline.
 * `#main .batas-px h1` is (1,1,1) and beats `#main h1` (1,0,1);
 * the `:is(.px-*)` forms are (1,2,0) and beat both.
 * ═══════════════════════════════════════════════════════════════════ */
#main .batas-px :is(h1, h2, h3, h4) {
	color: var(--px-ink);
	font-weight: 700;
	letter-spacing: -.015em;
	line-height: 1.3;
}
#main .batas-px .px-topbar-title { font-size: var(--px-fs-xl); letter-spacing: -.022em; }
#main .batas-px .px-sectionhead h3,
#main .batas-px .px-panel > h3 { font-size: var(--px-fs-lg); }
#main .batas-px :is(.px-topbar-sub, .px-hint, .px-softp, .px-bankcount, .px-aihint,
                    .px-savenote, .px-analysis, .px-markprog) { color: var(--px-soft); font-size: var(--px-fs-sm); }
#main .batas-px .px-card-course { margin: 4px 0 0; }
#main .batas-px .px-card-when { margin: 6px 0 0; }
#main .batas-px :is(.px-hint, .px-markprog, .px-bq-expl, .px-bq-src) { margin: 8px 0 0; }
#main .batas-px .px-analysis { margin: 16px 0 0; }
#main .batas-px .px-bankcount { margin: 0 0 12px; }
#main .batas-px .px-aihint { margin: 0 0 16px; }
#main .batas-px :is(.px-steps, .px-rubric, .px-bq-rubric) { padding-left: 20px; }
#main .batas-px .px-steps li { margin: 6px 0; }
#main .batas-px .px-bq-rubric li { margin: 0 0 4px; }
#main .batas-px .px-integrity ul { padding-left: 18px; margin: 8px 0 0; }
#main .batas-px .px-ai p { margin: 6px 0 0; }
#main .batas-px .px-empty p { margin: 0; }
#main .batas-px .px-gatecard p { margin: 0 0 var(--px-4); }

/* ═════════════════════════════════════════════════════════════════════
 * 3 · BANK HTML — .px-bq-text renders server-sanitised past-Bar essays
 * as-is. That markup carries <p>, <ul>, <blockquote>, <hr> and <table>,
 * none of which the app can reach with a class. Restyle rather than
 * zero: the theme's cream blockquote is the reading sheet's voice and
 * must not appear inside an app card.
 * ═══════════════════════════════════════════════════════════════════ */
#main .batas-px :is(.px-bq-text, .px-bq-answer) p { margin: 0 0 .7em; }
#main .batas-px :is(.px-bq-text, .px-bq-answer) p:last-child { margin-bottom: 0; }
#main .batas-px :is(.px-bq-text, .px-bq-answer) :is(ul, ol) { margin: .7em 0; padding-left: 22px; }
#main .batas-px :is(.px-bq-text, .px-bq-answer) li { margin: 0 0 .3em; }
#main .batas-px blockquote {
	margin: 12px 0; padding: 2px 0 2px 14px;
	border-left: 3px solid var(--px-line);
	background: none; border-radius: 0;
	color: var(--px-ink-2); font-style: normal;
}
#main .batas-px hr { margin: 16px 0; border: 0; border-top: 1px solid var(--px-line); }
#main .batas-px :is(.px-bq-text, .px-bq-answer) table {
	width: 100%; border-collapse: collapse; margin: 10px 0; font-size: var(--px-fs-md);
}
#main .batas-px :is(.px-bq-text, .px-bq-answer) :is(th, td) {
	border: 1px solid var(--px-line); padding: 6px 10px; text-align: left; vertical-align: top;
}

/* ═════════════════════════════════════════════════════════════════════
 * 4 · RESETS — the theme has no button/input rule anywhere, and
 * font-family does not inherit into form controls, so our buttons would
 * render in the UA's Arial beside `<a class="px-btn">`, which inherits.
 * ═══════════════════════════════════════════════════════════════════ */
.batas-px :is(button, input, select, textarea, optgroup) { font-family: inherit; }
.batas-px * { box-sizing: border-box; }
/* `a:hover { text-decoration: underline }` is (0,1,1) and beats
   `.px-btn { text-decoration: none }` (0,1,0). Scope the counter to
   button-shaped anchors — prose links inside bank HTML may underline. */
.batas-px :is(a.px-btn, a.px-mini):is(:hover, :focus-visible) { text-decoration: none; }

/* The lockup's classes live in frontend.css, which is NOT enqueued on
   this page — without these the gate renders an unsized 64-unit SVG. */
.batas-px .batas-xd-logo { display: inline-flex; align-items: center; gap: .45em; line-height: 1; }
.batas-px .batas-xd-mark { width: 1.5em; height: 1.5em; flex: none; display: block; }
.batas-px .batas-xd-word { font-weight: 800; letter-spacing: -.03em; color: #fff; font-size: 1.06rem; }
.batas-px .batas-xd-word b { font-weight: inherit; color: var(--exam-gold); }
/* On a light surface the mark's white calendar legs vanish — seat it. */
.batas-px-gate .batas-xd-word { color: var(--px-ink); }
.batas-px-gate .batas-xd-mark { background: var(--px-forest); border-radius: 7px; padding: 3px; }

/* ═════════════════════════════════════════════════════════════════════
 * 5 · TOKENS — one palette, one 4px grid, four radii, a rem type scale.
 * Colours point at the THEME's `:root` (style.css), which is always
 * loaded here. They deliberately do NOT point at `--batas-*`: those
 * live in frontend.css, which is not enqueued on this page, so such a
 * reference would only pretend to track the product.
 * Sizes are rem, never em, so nesting cannot compound.
 * ═══════════════════════════════════════════════════════════════════ */
.batas-px, .batas-px-gate {
	/* ink & surface */
	--px-ink:       var(--bt-ink, #17231f);
	--px-ink-2:     #4c5850;
	--px-soft:      var(--bt-ink-2, #6d746f);
	--px-faint:     var(--bt-ink-3, #878e87);
	--px-card:      #ffffff;
	--px-canvas:    var(--bt-canvas, #f4f0e7);
	--px-inset:     #f8f6ef;
	--px-line:      #e6e0d2;
	--px-line-soft: #f0ece1;

	/* one action colour — forest. There is no second one. */
	--px-accent:      var(--bt-accent, #173b32);
	--px-accent-hi:   var(--bt-accent-hover, #214d41);
	--px-accent-wash: rgba(23, 59, 50, .07);

	/* the wall, and the flourish */
	--px-forest:   #101d18;
	--exam-gold:   #eaa819;
	--px-gold-ink: #8a6510;

	/* semantics */
	--px-ok:      #1a7f37;
	--px-ok-bg:   rgba(26, 127, 55, .12);
	--px-ok-ink:  #14532d;
	--px-warn-bg: #fff7e6;
	--px-warn-ink:#92400e;
	--px-err:     #9b3a31;
	--px-err-bg:  #fdecec;
	--px-err-ink: #7f1d1d;

	/* space — a 4px grid, seven steps, nothing between them */
	--px-1: 4px; --px-2: 8px; --px-3: 12px; --px-4: 16px;
	--px-5: 24px; --px-6: 32px; --px-7: 48px;

	/* radius — four steps, down from seven */
	--px-r-1: 6px;      /* tags, letter tokens, item-analysis pills */
	--px-r-2: 8px;      /* every control, input and inner surface */
	--px-r-3: 12px;     /* every card, panel and tile */
	--px-r-pill: 999px; /* status chips only */

	/* type — rem. The app is a dense tool at 15px; prose the professor
	   actually READS (bank questions, essays) is lifted back to 17px. */
	--px-fs-xs:   .75rem;
	--px-fs-sm:   .8125rem;
	--px-fs-md:   .875rem;
	--px-fs-base: .9375rem;
	--px-fs-lg:   1.0625rem;
	--px-fs-xl:   1.375rem;
	--px-fs-num:  1.75rem;

	/* elevation — four rungs; a resting card has NONE */
	--px-lift-1: 0 1px 2px rgba(16, 35, 29, .05);
	--px-lift-2: 0 6px 20px rgba(16, 35, 29, .10);
	--px-lift-3: 0 16px 40px rgba(12, 36, 30, .22);

	/* chrome geometry — --px-site-header is measured by proctor.js */
	--px-rail: 232px;
	--px-site-header: 60px;
	--px-chrome: calc(var(--px-site-header) + var(--wp-admin--admin-bar--height, 0px));

	color: var(--px-ink);
	font-size: var(--px-fs-base);
	line-height: 1.55;
}

/* ═════════════════════════════════════════════════════════════════════
 * 6 · SHELL — one object: a forest wall down the left, the workspace to
 * its right, both inside a single hairline. The rail STRETCHES to the
 * row height, which is the whole difference between chrome and "a dark
 * box floating in a page".
 *
 * `overflow: clip`, never `hidden`: hidden creates a programmatically
 * scrollable box and re-parents sticky descendants to it.
 * ═══════════════════════════════════════════════════════════════════ */
.batas-px { min-width: 0; }
.px-shell {
	display: grid;
	grid-template-columns: var(--px-rail) minmax(0, 1fr);
	background: var(--px-card);
	border: 1px solid var(--px-line);
	border-radius: var(--px-r-3);
	overflow: clip;
	min-height: 520px;
}
.batas-px-loading { padding: var(--px-7) 0; text-align: center; color: var(--px-soft); }

/* ---- the wall ---- */
.px-rail {
	background: var(--px-forest);
	color: #fff;
	display: flex;
	flex-direction: column;
	min-width: 0;
}
.px-rail-inner {
	position: sticky;
	top: calc(var(--px-chrome) + var(--px-3));
	display: flex;
	flex-direction: column;
	gap: var(--px-4);
	padding: var(--px-4) var(--px-3);
	min-height: 0;
}
.px-brand { display: flex; align-items: center; padding: var(--px-1) var(--px-2) var(--px-4); }
.px-brand-fallback { font-weight: 800; font-size: 1.06rem; color: #fff; }
.px-railnav { display: flex; flex-direction: column; gap: 2px; }
.px-railbtn {
	display: flex; align-items: center; gap: var(--px-3);
	width: 100%; border: 0; background: none;
	color: rgba(255, 255, 255, .72);
	font: inherit; font-size: var(--px-fs-md); font-weight: 600;
	text-align: left;
	padding: 10px var(--px-3);
	border-radius: var(--px-r-2);
	cursor: pointer;
	position: relative;
	transition: background .15s, color .15s;
}
.px-railbtn:hover { background: rgba(255, 255, 255, .07); color: #fff; }
/* The active state must not be carried by colour alone (WCAG 1.4.1):
   a gold spine + a weight bump survive greyscale. */
.px-railbtn.is-on { background: rgba(234, 168, 25, .15); color: var(--exam-gold); font-weight: 800; }
.px-railbtn.is-on::before {
	content: ""; position: absolute; left: 0; top: 8px; bottom: 8px;
	width: 3px; border-radius: 0 3px 3px 0; background: var(--exam-gold);
}
.px-ic { width: 18px; height: 18px; flex: none; display: block; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.px-railbtn-l { min-width: 0; }
.px-railbtn-s { display: none; }
.px-rail-foot { margin-top: auto; display: flex; flex-direction: column; gap: var(--px-3); padding-top: var(--px-4); }
.px-rail-user { display: flex; flex-direction: column; gap: 1px; padding: 0 var(--px-2); font-size: var(--px-fs-xs); border-top: 1px solid rgba(255, 255, 255, .12); padding-top: var(--px-3); }
.px-rail-name { color: rgba(255, 255, 255, .82); font-weight: 600; }
.px-rail-quota { color: rgba(255, 255, 255, .58); }

/* the staging tray, on the wall */
.px-tray {
	display: grid; gap: var(--px-2);
	background: rgba(234, 168, 25, .13);
	border: 1px solid rgba(234, 168, 25, .42);
	border-radius: var(--px-r-2);
	padding: var(--px-3);
	font-size: var(--px-fs-sm);
}
.px-tray[hidden] { display: none; }
.px-tray strong { color: var(--exam-gold); font-weight: 700; }
.px-tray-row { display: flex; gap: var(--px-2); align-items: center; }
.px-tray .px-mini { background: transparent; border-color: rgba(255, 255, 255, .32); color: #fff; flex: 1 1 auto; }
.px-tray .px-mini:hover { border-color: #fff; background: rgba(255, 255, 255, .08); }

/* ---- the workspace ---- */
.px-work { display: flex; flex-direction: column; min-width: 0; container-type: inline-size; container-name: pxpane; }
/* ⚠ container-type makes .px-work a containing block for FIXED
   descendants. Nothing position:fixed may live in here — .px-toast is
   appended to <body> on purpose, and any future modal must portal out.
   This is the same trap that broke the landing pitch-show stage. */

.px-topbar {
	position: sticky; top: var(--px-chrome); z-index: 5;
	display: flex; align-items: center; gap: var(--px-3);
	padding: var(--px-3) var(--px-5);
	background: rgba(255, 255, 255, .92);
	backdrop-filter: saturate(160%) blur(8px);
	border-bottom: 1px solid var(--px-line);
	min-height: 60px;
}
.px-topbar-id { min-width: 0; flex: 1 1 auto; }
.px-topbar-title { margin: 0; }
.px-topbar-sub { margin: 2px 0 0; max-width: 76ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.px-topbar-sub[hidden] { display: none; }
.px-topbar-actions { display: flex; align-items: center; gap: var(--px-2); flex: none; }
.px-topbar-back {
	flex: none; display: inline-flex; align-items: center; justify-content: center;
	width: 34px; height: 34px; border: 1px solid var(--px-line); border-radius: var(--px-r-2);
	background: var(--px-card); color: var(--px-ink); cursor: pointer;
}
.px-topbar-back:hover { background: var(--px-inset); }
.px-topbar-back[hidden] { display: none; }

.px-main { padding: var(--px-5); min-width: 0; }

/* ═════════════════════════════════════════════════════════════════════
 * 7 · CONTROLS
 * ═══════════════════════════════════════════════════════════════════ */
.px-btn {
	display: inline-flex; align-items: center; justify-content: center; gap: 6px;
	border: 1px solid var(--px-line); background: var(--px-card); color: var(--px-ink);
	border-radius: var(--px-r-2); padding: 9px 16px;
	font-size: var(--px-fs-md); font-weight: 600; line-height: 1.2;
	cursor: pointer; text-decoration: none;
	transition: background .15s, border-color .15s;
}
.px-btn:hover { border-color: #d7cfbc; background: var(--px-inset); }
.px-btn.is-primary { background: var(--px-accent); border-color: var(--px-accent); color: #fff; }
.px-btn.is-primary:hover { background: var(--px-accent-hi); border-color: var(--px-accent-hi); }
.px-btn.is-danger { color: var(--px-err); }
.px-btn.is-danger:hover { border-color: var(--px-err); background: var(--px-err-bg); }
.px-btn[disabled] { opacity: .45; cursor: default; }
.px-mini {
	display: inline-flex; align-items: center; justify-content: center; gap: 5px;
	border: 1px solid var(--px-line); background: var(--px-card); color: var(--px-ink);
	border-radius: var(--px-r-2); padding: 6px 11px; min-height: 30px;
	font-size: var(--px-fs-sm); font-weight: 600; line-height: 1.2; cursor: pointer; text-decoration: none;
}
.px-mini:hover { border-color: #d7cfbc; background: var(--px-inset); }
.px-mini.is-primary { background: var(--px-accent); border-color: var(--px-accent); color: #fff; }
.px-mini.is-primary:hover { background: var(--px-accent-hi); }
.px-mini.is-danger { color: var(--px-err); }
/* icon-only controls need a real target, not a glyph-sized one */
.px-iconbtn {
	display: inline-flex; align-items: center; justify-content: center;
	min-width: 32px; min-height: 32px; padding: 0;
	border: 1px solid var(--px-line); border-radius: var(--px-r-2);
	background: var(--px-card); color: var(--px-ink); cursor: pointer;
}
.px-iconbtn:hover { border-color: #d7cfbc; background: var(--px-inset); }
.px-iconbtn.is-onwall { background: transparent; border-color: rgba(255, 255, 255, .32); color: #fff; }
.px-iconbtn.is-danger:hover { border-color: var(--px-err); color: var(--px-err); background: var(--px-err-bg); }
.px-linklike { background: none; border: 0; padding: 0; font: inherit; font-weight: 600; color: var(--px-accent); cursor: pointer; text-align: left; }
.px-linklike:hover { text-decoration: underline; }

/* focus — one ring, retuned on the dark wall where the accent can't carry 3:1 */
.batas-px :is(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
	outline: 2px solid var(--px-accent); outline-offset: 2px; border-radius: var(--px-r-2);
}
.px-rail :focus-visible { outline-color: var(--exam-gold); }

/* ---- chips (STATE) and tags (PROVENANCE) are different things ---- */
.px-chip {
	display: inline-flex; align-items: center;
	font-size: var(--px-fs-xs); font-weight: 700; letter-spacing: .03em; text-transform: uppercase;
	border-radius: var(--px-r-pill); padding: 3px 10px;
	background: #f0ece1; color: var(--px-soft); white-space: nowrap;
}
.px-chip.is-open, .px-chip.is-approved, .px-chip.is-released, .px-chip.is-clean { background: var(--px-ok-bg); color: var(--px-ok-ink); }
.px-chip.is-pending, .px-chip.is-draft { background: var(--px-warn-bg); color: var(--px-warn-ink); }
.px-chip.is-closed { background: #ece7db; color: var(--px-soft); }
.px-chip.is-flag { background: var(--px-err-bg); color: var(--px-err-ink); }
.px-tag {
	display: inline-flex; align-items: center;
	font-size: var(--px-fs-xs); font-weight: 600;
	border: 1px solid var(--px-line); border-radius: var(--px-r-1);
	padding: 2px 8px; color: var(--px-soft); background: none; white-space: nowrap;
}
.px-tag.is-bar { border-color: var(--px-forest); background: var(--px-forest); color: var(--exam-gold); }
.px-quota { font-size: var(--px-fs-sm); color: var(--px-soft); background: var(--px-card); border: 1px solid var(--px-line); border-radius: var(--px-r-pill); padding: 5px 12px; white-space: nowrap; }
.px-quota.is-out { color: var(--px-err); border-color: var(--px-err); }

/* ---- the ONE switch component, at three sizes ---- */
.px-switch {
	display: flex; gap: 2px; padding: 3px;
	background: var(--px-inset); border: 1px solid var(--px-line);
	border-radius: var(--px-r-2);
	overflow-x: auto; scrollbar-width: none; max-width: 100%;
}
.px-switch::-webkit-scrollbar { display: none; }
.px-switchbtn {
	border: 0; background: none; border-radius: var(--px-r-1);
	padding: 7px 14px; font: inherit; font-size: var(--px-fs-sm); font-weight: 700;
	color: var(--px-soft); cursor: pointer; white-space: nowrap;
}
.px-switchbtn:hover { color: var(--px-ink); }
.px-switchbtn.is-on { background: var(--px-card); color: var(--px-ink); box-shadow: var(--px-lift-1); }
.px-switch.is-sm .px-switchbtn { padding: 5px 11px; font-size: var(--px-fs-xs); }

/* ═════════════════════════════════════════════════════════════════════
 * 8 · SURFACES — ONE border per nesting level. A card has a hairline;
 * everything inside it separates with tint, padding and space.
 * ═══════════════════════════════════════════════════════════════════ */
.px-panel { background: var(--px-card); border: 1px solid var(--px-line); border-radius: var(--px-r-3); padding: var(--px-5); margin: 0 0 var(--px-4); }
.px-panel > h3 { margin: 0 0 var(--px-3); }
.px-sectionhead { display: flex; align-items: center; justify-content: space-between; gap: var(--px-3); flex-wrap: wrap; margin: 0 0 var(--px-3); }
.px-sectionhead h3 { margin: 0; }
.px-sectionhead h3 small { color: var(--px-soft); font-weight: 400; font-size: var(--px-fs-sm); margin-left: 6px; }
.px-sectionhead-actions { display: flex; gap: var(--px-2); flex-wrap: wrap; }
.px-empty { background: var(--px-card); border: 1px dashed var(--px-line); border-radius: var(--px-r-3); padding: var(--px-6) var(--px-5); text-align: center; color: var(--px-soft); }
.px-empty.is-error { border-style: solid; border-color: var(--px-err); background: var(--px-err-bg); color: var(--px-err-ink); }
.px-softp { margin: 0; }
.px-actions { display: flex; gap: var(--px-2); flex-wrap: wrap; margin-top: var(--px-3); }

/* Overview: ONE tile strip, one border, columns divided by hairlines */
.px-tiles {
	display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 150px), 1fr));
	background: var(--px-card); border: 1px solid var(--px-line); border-radius: var(--px-r-3);
	overflow: clip; margin: 0 0 var(--px-4);
}
.px-tile { padding: var(--px-4) var(--px-5); border-left: 1px solid var(--px-line-soft); }
.px-tile:first-child { border-left: 0; }
.px-tile strong { display: block; font-size: var(--px-fs-num); line-height: 1.1; letter-spacing: -.03em; font-weight: 700; }
.px-tile span { font-size: var(--px-fs-sm); color: var(--px-soft); font-weight: 600; }
.px-tile.is-warn { background: var(--px-warn-bg); }
.px-tile.is-warn strong { color: var(--px-gold-ink); }

.px-cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)); gap: var(--px-4); }
.px-up, .px-att { list-style: none; display: flex; flex-direction: column; gap: var(--px-2); }
.px-up button, .px-att button {
	display: block; width: 100%; text-align: left; background: none;
	border: 1px solid var(--px-line); border-radius: var(--px-r-2);
	padding: 10px var(--px-3); font: inherit; color: inherit; cursor: pointer;
	transition: border-color .15s, background .15s;
}
.px-up button:hover, .px-att button:hover { border-color: #d7cfbc; background: var(--px-inset); }
.px-up strong, .px-att strong { display: block; font-size: var(--px-fs-base); }
.px-up span, .px-att span { font-size: var(--px-fs-sm); color: var(--px-soft); }
.px-att span { color: var(--px-gold-ink); font-weight: 600; }
.px-quickrow { display: flex; gap: var(--px-2); flex-wrap: wrap; }

/* Exam cards */
.px-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 288px), 1fr)); gap: var(--px-4); }
.px-card { background: var(--px-card); border: 1px solid var(--px-line); border-radius: var(--px-r-3); padding: var(--px-4) var(--px-5); transition: box-shadow .15s, transform .15s, border-color .15s; }
.px-card:hover { box-shadow: var(--px-lift-2); transform: translateY(-1px); border-color: #d7cfbc; }
.px-card-top { display: flex; justify-content: space-between; align-items: flex-start; gap: var(--px-2); }
.px-card-title { margin: 0; font-size: var(--px-fs-base); min-width: 0; }
.px-card-link { background: none; border: 0; padding: 0; font: inherit; font-weight: 700; color: var(--px-ink); text-align: left; cursor: pointer; }
.px-card-link::after { content: ""; position: absolute; inset: 0; border-radius: inherit; }
.px-card { position: relative; }
.px-card-link:hover { color: var(--px-accent); }
.px-card-course { color: var(--px-soft); font-size: var(--px-fs-sm); }
.px-card-when { font-size: var(--px-fs-sm); }
.px-card-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(50%, 62px), 1fr)); gap: var(--px-2); margin-top: var(--px-3); padding-top: var(--px-3); border-top: 1px solid var(--px-line-soft); }
.px-card-stats > div { min-width: 0; }
.px-card-stats dt { font-size: var(--px-fs-xs); color: var(--px-soft); }
.px-card-stats dd { margin: 0; font-size: var(--px-fs-md); font-weight: 700; }
.px-card-stats dd.is-pending { color: var(--px-gold-ink); }

/* ---- codes ---- */
.px-code { display: flex; align-items: center; gap: var(--px-2); flex-wrap: wrap; padding: var(--px-3); border: 1px solid var(--px-line); border-radius: var(--px-r-2); margin-bottom: var(--px-2); background: var(--px-inset); }
.px-code span { flex: 1 1 100%; font-size: var(--px-fs-xs); color: var(--px-soft); }
.px-code strong { font-family: ui-monospace, "Cascadia Mono", Consolas, monospace; font-size: 1.15rem; letter-spacing: .08em; }
.px-code.is-secret strong { color: var(--px-gold-ink); }

/* ═════════════════════════════════════════════════════════════════════
 * 9 · FORMS + EDITOR
 * ═══════════════════════════════════════════════════════════════════ */
.px-field { display: block; margin: 0 0 var(--px-3); min-width: 0; }
.px-field > span { display: block; font-size: var(--px-fs-sm); font-weight: 600; color: var(--px-soft); margin-bottom: 5px; }
.px-field :is(input[type=text], input[type=number], input[type=datetime-local], input[type=search], textarea, select) {
	width: 100%; border: 1px solid var(--px-line); border-radius: var(--px-r-2);
	padding: 9px var(--px-3); font: inherit; font-size: var(--px-fs-base);
	background: var(--px-card); color: var(--px-ink);
}
.px-field textarea { resize: vertical; }
.px-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 210px), 1fr)); gap: var(--px-3); }
.px-field-min { max-width: 220px; }
.px-checks { display: flex; gap: var(--px-5); flex-wrap: wrap; margin: var(--px-1) 0 var(--px-3); font-size: var(--px-fs-base); }
.px-checks label { display: flex; align-items: center; gap: var(--px-2); }
.px-q { background: var(--px-card); border: 1px solid var(--px-line); border-left: 3px solid var(--px-accent); border-radius: var(--px-r-2); padding: var(--px-4); margin: 0 0 var(--px-3); }
.px-q[data-type=essay] { border-left-color: var(--exam-gold); }
.px-q-head { display: flex; justify-content: space-between; align-items: center; gap: var(--px-2); margin-bottom: var(--px-2); flex-wrap: wrap; }
.px-q-tools { display: flex; align-items: center; gap: var(--px-1); font-size: var(--px-fs-sm); }
.px-q-tools label { display: flex; align-items: center; gap: 6px; color: var(--px-soft); }
.px-q-points { width: 68px; border: 1px solid var(--px-line); border-radius: var(--px-r-2); padding: 5px 8px; font: inherit; font-size: var(--px-fs-sm); }
.px-q-text { width: 100%; border: 1px solid var(--px-line); border-radius: var(--px-r-2); padding: 9px var(--px-3); font: inherit; font-size: var(--px-fs-base); margin-bottom: var(--px-2); resize: vertical; }
.px-opts { display: flex; flex-direction: column; gap: var(--px-2); }
.px-opt { display: flex; align-items: center; gap: var(--px-2); }
.px-opt-text { flex: 1; min-width: 0; border: 1px solid var(--px-line); border-radius: var(--px-r-2); padding: 7px 10px; font: inherit; font-size: var(--px-fs-base); }
.px-opt input[type=radio] { width: 18px; height: 18px; flex: none; accent-color: var(--px-accent); }
.px-opt-add { margin-top: var(--px-2); }
.px-addrow { display: flex; gap: var(--px-2); margin: var(--px-1) 0 var(--px-4); flex-wrap: wrap; }
/* The save bar rides the workspace floor — authoring a 60-question exam
   must not mean scrolling to the bottom to find Save. */
.px-savebar {
	position: sticky; bottom: 0; z-index: 4;
	display: flex; align-items: center; gap: var(--px-3); flex-wrap: wrap;
	border-top: 1px solid var(--px-line); padding: var(--px-3) 0;
	margin-top: var(--px-4);
	background: rgba(255, 255, 255, .94);
	backdrop-filter: saturate(160%) blur(8px);
}
.px-draftbar { display: flex; align-items: center; gap: var(--px-3); flex-wrap: wrap; margin: 0 0 var(--px-4); padding: var(--px-3) var(--px-4); background: var(--px-warn-bg); border: 1px solid #e8d9a8; border-radius: var(--px-r-2); font-size: var(--px-fs-sm); }
.px-draftbar span { flex: 1 1 auto; }
.px-traybar { display: flex; align-items: center; justify-content: space-between; gap: var(--px-3); flex-wrap: wrap; background: var(--px-warn-bg); border: 1px solid #e8d9a8; border-radius: var(--px-r-2); padding: var(--px-3) var(--px-4); margin: 0 0 var(--px-3); font-size: var(--px-fs-sm); }
.px-traybar strong { color: var(--px-gold-ink); }
.px-traybar-btns { display: flex; gap: var(--px-2); }

/* ═════════════════════════════════════════════════════════════════════
 * 10 · TABLES — no sticky heads: .px-tablewrap sets overflow-x, which
 * computes overflow-y to auto and makes it the scrollport, so a sticky
 * th would resolve against a box with no vertical overflow and never
 * move. The Student column stays put instead.
 * ═══════════════════════════════════════════════════════════════════ */
.px-tablewrap { overflow-x: auto; -webkit-overflow-scrolling: touch; margin: 0 calc(-1 * var(--px-2)); padding: 0 var(--px-2); }
.px-table { width: 100%; border-collapse: collapse; font-size: var(--px-fs-md); }
.px-table th { text-align: left; font-size: var(--px-fs-xs); text-transform: uppercase; letter-spacing: .05em; color: var(--px-soft); padding: var(--px-2) var(--px-3); border-bottom: 1px solid var(--px-line); white-space: nowrap; }
.px-table td { padding: var(--px-3); border-bottom: 1px solid var(--px-line-soft); vertical-align: top; }
.px-table small { color: var(--px-soft); }
.px-table tr:last-child td { border-bottom: 0; }
.px-attempt-row:hover td { background: var(--px-inset); }
.px-reg-actions { display: flex; gap: 6px; flex-wrap: wrap; }
.px-item { display: inline-block; background: var(--px-inset); border: 1px solid var(--px-line); border-radius: var(--px-r-1); padding: 2px 8px; margin: 2px; font-size: var(--px-fs-xs); }
.px-item.is-hard { background: var(--px-err-bg); color: var(--px-err-ink); border-color: #eccfcb; font-weight: 700; }

/* ═════════════════════════════════════════════════════════════════════
 * 11 · ATTEMPT REVIEW + MARKING — inner surfaces are borderless.
 * ═══════════════════════════════════════════════════════════════════ */
.px-integrity summary { cursor: pointer; color: var(--px-err); font-weight: 600; font-size: var(--px-fs-sm); }
.px-integrity ul { font-size: var(--px-fs-sm); }
.px-clean { color: var(--px-ok); font-size: var(--px-fs-sm); }
.px-a-q { border-top: 1px solid var(--px-line-soft); padding: var(--px-4) 0; }
.px-a-qhead { display: flex; justify-content: space-between; font-size: var(--px-fs-sm); color: var(--px-soft); margin-bottom: 6px; }
.px-a-qtext { font-weight: 600; margin-bottom: var(--px-2); white-space: pre-wrap; }
.px-a-opts { list-style: none; display: flex; flex-direction: column; gap: 6px; }
.px-a-opts li { padding: var(--px-2) var(--px-3); border-radius: var(--px-r-2); font-size: var(--px-fs-base); background: var(--px-inset); }
.px-a-opts li.is-key { background: var(--px-ok-bg); color: var(--px-ok-ink); font-weight: 600; }
.px-a-opts li.is-wrong { background: var(--px-err-bg); color: var(--px-err-ink); }
/* "the student picked this" must be visible even when it IS the key */
.px-a-opts li.is-chosen { box-shadow: inset 3px 0 0 currentColor; }
.px-a-essay { background: var(--px-inset); border-radius: var(--px-r-2); padding: var(--px-4); font-size: var(--px-fs-lg); line-height: 1.6; white-space: pre-wrap; max-width: 68ch; }
.px-ai { background: var(--px-accent-wash); border-left: 3px solid var(--px-accent); border-radius: 0 var(--px-r-2) var(--px-r-2) 0; padding: var(--px-3) var(--px-4); margin: var(--px-2) 0; font-size: var(--px-fs-sm); }
.px-ai.is-none { background: var(--px-inset); border-left-color: var(--px-line); color: var(--px-soft); }
.px-alac span { display: inline-block; border-radius: var(--px-r-1); padding: 2px 8px; margin-right: 4px; font-size: var(--px-fs-xs); background: var(--px-inset); }
.px-alac span.is-strong { background: var(--px-ok-bg); color: var(--px-ok-ink); }
.px-alac span.is-partial { background: var(--px-warn-bg); color: var(--px-warn-ink); }
.px-alac span.is-weak { background: var(--px-err-bg); color: var(--px-err-ink); }
.px-override { display: flex; align-items: center; gap: var(--px-2); margin-top: var(--px-2); flex-wrap: wrap; }
.px-override label { display: flex; align-items: center; gap: var(--px-2); font-size: var(--px-fs-sm); color: var(--px-soft); font-weight: 600; }
.px-override input[type=number] { width: 84px; border: 1px solid var(--px-line); border-radius: var(--px-r-2); padding: 6px 8px; font: inherit; font-size: var(--px-fs-base); }
.px-override input[type=text] { flex: 1; min-width: 200px; border: 1px solid var(--px-line); border-radius: var(--px-r-2); padding: 6px 10px; font: inherit; font-size: var(--px-fs-base); }
.px-qpick { display: flex; flex-wrap: wrap; gap: var(--px-2); margin-top: var(--px-3); }
.px-marking .px-qtext { background: var(--px-inset); border-radius: var(--px-r-2); padding: var(--px-4); margin: var(--px-3) 0; white-space: pre-wrap; font-size: var(--px-fs-lg); line-height: 1.6; max-width: 68ch; }
.px-rubric { margin: 0 0 var(--px-4); color: var(--px-soft); font-size: var(--px-fs-sm); }
.px-blind { display: flex; align-items: center; gap: 6px; font-size: var(--px-fs-sm); color: var(--px-soft); font-weight: 600; }
.px-mark { border: 1px solid var(--px-line); border-left: 3px solid var(--px-line); border-radius: var(--px-r-2); padding: var(--px-4); margin: var(--px-3) 0; background: var(--px-card); }
.px-mark.is-marked { border-left-color: var(--px-ok); }
.px-mark header { display: flex; align-items: center; gap: var(--px-2); margin-bottom: var(--px-2); }
.px-mark header strong { flex: 1 1 auto; }
.px-marktick { font-size: var(--px-fs-sm); color: var(--px-soft); font-weight: 700; }
.px-mark.is-marked .px-marktick { color: var(--px-ok); }

/* ═════════════════════════════════════════════════════════════════════
 * 12 · BANK + AI WRITER
 * ═══════════════════════════════════════════════════════════════════ */
.px-filters { display: flex; gap: var(--px-2); flex-wrap: wrap; align-items: center; margin: 0 0 var(--px-4); }
.px-filters input[type=search] { flex: 1 1 220px; min-width: 0; border: 1px solid var(--px-line); border-radius: var(--px-r-2); padding: 8px var(--px-3); font: inherit; font-size: var(--px-fs-base); background: var(--px-card); }
.px-filters select { border: 1px solid var(--px-line); border-radius: var(--px-r-2); padding: 8px 10px; font: inherit; font-size: var(--px-fs-sm); background: var(--px-card); color: var(--px-ink); max-width: 100%; }
.px-pager { display: flex; align-items: center; justify-content: center; gap: var(--px-4); margin: var(--px-5) 0 0; font-size: var(--px-fs-sm); color: var(--px-soft); }

.px-bq-list { display: flex; flex-direction: column; gap: var(--px-3); }
.px-bq { background: var(--px-card); border: 1px solid var(--px-line); border-radius: var(--px-r-3); padding: var(--px-5); }
.px-bq-chips { display: flex; gap: 6px; flex-wrap: wrap; margin: 0 0 var(--px-3); }
/* A Bar question is READ, not scanned — 17px with a real measure. */
.px-bq-text { font-size: var(--px-fs-lg); line-height: 1.6; max-width: 68ch; }
.px-bq-opts { display: flex; flex-direction: column; gap: 5px; margin: var(--px-3) 0 0; font-size: var(--px-fs-base); list-style: none; counter-reset: pxopt; }
.px-bq-opts li { padding-left: 26px; position: relative; }
.px-bq-opts li::before { counter-increment: pxopt; content: counter(pxopt, upper-alpha); position: absolute; left: 0; top: 1px; width: 19px; height: 19px; display: inline-flex; align-items: center; justify-content: center; background: var(--px-inset); border-radius: var(--px-r-1); font-size: var(--px-fs-xs); font-weight: 700; color: var(--px-soft); }
.px-bq-opts li.is-key { color: var(--px-ok-ink); font-weight: 600; }
.px-bq-opts li.is-key::before { background: var(--px-ok-bg); color: var(--px-ok-ink); }
.px-bq-expl { font-size: var(--px-fs-sm); color: var(--px-soft); border-left: 3px solid var(--px-line); padding-left: var(--px-3); }
.px-bq-key { margin: var(--px-3) 0 0; font-size: var(--px-fs-base); }
.px-bq-key summary { cursor: pointer; font-weight: 700; color: var(--px-accent); font-size: var(--px-fs-sm); }
.px-bq-answer { margin: var(--px-3) 0 0; background: var(--px-inset); border-radius: var(--px-r-2); padding: var(--px-3) var(--px-4); font-size: var(--px-fs-lg); line-height: 1.6; max-width: 68ch; }
.px-bq-rubric { margin: var(--px-3) 0 0; }
.px-bq-src { font-size: var(--px-fs-xs); color: var(--px-faint); }
.px-bq-actions { display: flex; gap: 6px; flex-wrap: wrap; margin: var(--px-4) 0 0; padding-top: var(--px-3); border-top: 1px solid var(--px-line-soft); }

.px-ainote { background: var(--px-warn-bg); border: 1px solid #e8d9a8; border-radius: var(--px-r-2); padding: var(--px-3) var(--px-4); margin: 0 0 var(--px-4); font-size: var(--px-fs-sm); }
.px-aisrc { display: flex; align-items: center; gap: var(--px-2); flex-wrap: wrap; background: var(--px-inset); border-radius: var(--px-r-2); padding: var(--px-2) var(--px-3); margin: 0 0 var(--px-3); font-size: var(--px-fs-sm); }
.px-aisrc-text { flex: 1 1 240px; color: var(--px-soft); }
.px-airesults-head { display: flex; align-items: center; justify-content: space-between; gap: var(--px-3); flex-wrap: wrap; margin: var(--px-5) 0 var(--px-3); }
.px-airesults-head h3 { margin: 0; }

/* ═════════════════════════════════════════════════════════════════════
 * 13 · TOAST + GATE
 * .px-toast is appended to <body> deliberately: .px-work declares
 * container-type, which would trap a fixed descendant.
 * ═══════════════════════════════════════════════════════════════════ */
.px-toast { position: fixed; left: 50%; bottom: 28px; transform: translate(-50%, 16px); background: var(--px-forest, #101d18); color: #fff; border-radius: var(--px-r-2); padding: 10px 18px; font-size: .9rem; opacity: 0; transition: opacity .2s, transform .2s; z-index: 99999; max-width: min(92vw, 460px); }
.px-toast.is-on { opacity: 1; transform: translate(-50%, 0); }
.px-toast.is-err { background: var(--px-err, #9b3a31); }

.batas-px-gate { padding: var(--px-6) 0; }
.px-gatecard { max-width: 520px; margin: 0 auto; background: var(--px-card); border: 1px solid var(--px-line); border-radius: var(--px-r-3); padding: var(--px-7) var(--px-5); text-align: center; }
.px-gatecard .batas-xd-logo { justify-content: center; margin-bottom: var(--px-4); font-size: 1.15rem; }
#main .batas-px-gate h2 { font-size: var(--px-fs-xl); margin: 0 0 var(--px-2); color: var(--px-ink); font-weight: 700; }
.px-gatecard p { color: var(--px-soft); }

.px-visually-hidden { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }

/* ═════════════════════════════════════════════════════════════════════
 * 14 · RESPONSIVE — the rail changes STATE: wall → spine → floor.
 * Grids are intrinsic (auto-fit + minmax(min(100%, N), 1fr)) so they
 * respond to the CONTAINER, not the viewport; only the shell states
 * below need queries.
 * ═══════════════════════════════════════════════════════════════════ */

/* 1180px — the wall keeps its width but drops its labels. */
@media (min-width: 900px) and (max-width: 1180px) {
	.batas-px { --px-rail: 76px; }
	.px-rail-inner { padding: var(--px-4) var(--px-2); }
	.px-railbtn { justify-content: center; padding: 11px 0; gap: 0; }
	.px-railbtn-l, .px-railbtn-s, .px-rail-user, .px-brand .batas-xd-word {
		position: absolute; width: 1px; height: 1px; margin: -1px;
		padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
	}
	.px-brand { justify-content: center; padding-inline: 0; }
	.px-tray { padding: var(--px-2); justify-items: center; text-align: center; }
	.px-tray .px-mini, .px-tray-row { display: none; }
	.px-main { padding: var(--px-4); }
	.px-topbar { padding: var(--px-3) var(--px-4); }
}

/* 899px — the wall becomes a floor. The quota moves to the app bar, so
   it is no longer deleted on phones the way the old rail foot was. */
@media (max-width: 899px) {
	.px-shell { grid-template-columns: minmax(0, 1fr); min-height: 0; }
	.px-rail {
		position: fixed; inset: auto 0 0 0; z-index: 60;
		flex-direction: row;
		padding: 6px 8px calc(6px + env(safe-area-inset-bottom));
		border-top: 1px solid rgba(255, 255, 255, .1);
		box-shadow: 0 -6px 24px rgba(12, 36, 30, .28);
	}
	.px-rail-inner { position: static; flex-direction: row; align-items: center; width: 100%; padding: 0; gap: 0; }
	.px-brand, .px-rail-user { display: none; }
	.px-rail-foot { margin: 0; padding: 0; }
	.px-railnav { flex-direction: row; flex: 1 1 auto; gap: 0; width: 100%; }
	.px-railbtn { flex: 1 1 0; flex-direction: column; gap: 3px; padding: 6px 2px; min-width: 0; }
	.px-railbtn-l { display: none; }
	.px-railbtn-s { display: block; font-size: 10px; line-height: 1.15; text-align: center; letter-spacing: .01em; }
	.px-railbtn.is-on { background: none; }
	.px-railbtn.is-on::before { left: 50%; right: auto; top: -6px; bottom: auto; width: 24px; height: 3px; transform: translateX(-50%); border-radius: 0 0 3px 3px; }
	.px-main { padding: var(--px-4) var(--px-4) calc(var(--px-7) + 64px); }
	.px-topbar { padding: var(--px-3) var(--px-4); }
	.px-savebar { bottom: calc(64px + env(safe-area-inset-bottom)); }
	/* the tray floats clear of the tab bar so a staged question is never lost */
	.px-tray {
		position: fixed; left: 12px; right: 12px;
		bottom: calc(72px + env(safe-area-inset-bottom)); z-index: 61;
		background: var(--px-forest); box-shadow: var(--px-lift-3);
	}
	.px-tray-row { display: flex; }
}

/* 560px — the app bar goes to two rows so actions never squeeze the title. */
@media (max-width: 560px) {
	.px-topbar { flex-wrap: wrap; row-gap: var(--px-2); }
	.px-topbar-id { flex: 1 1 100%; order: 1; }
	.px-topbar-back { order: 0; }
	.px-topbar-actions { flex: 1 1 100%; order: 2; justify-content: flex-start; flex-wrap: wrap; }
	.px-topbar-title { font-size: 1.1875rem; }
	.px-topbar-sub { white-space: normal; }
	.px-panel, .px-bq { padding: var(--px-4); }
	.px-main { padding: var(--px-3) var(--px-3) calc(var(--px-7) + 64px); }
	.px-sectionhead-actions { width: 100%; }
	.px-sectionhead-actions .px-btn, .px-sectionhead-actions .px-mini { flex: 1 1 auto; }
}

/* Touch: catches tablets and touch laptops that never hit a width query. */
@media (pointer: coarse) {
	.px-btn { min-height: 40px; }
	.px-mini { min-height: 34px; }
	.px-iconbtn { min-width: 40px; min-height: 40px; }
	.px-switchbtn { min-height: 36px; }
}

@media (prefers-reduced-motion: reduce) {
	.batas-px *, .px-toast { transition-duration: .001ms !important; animation-duration: .001ms !important; }
	.px-card:hover { transform: none; }
	.px-toast, .px-toast.is-on { transform: translate(-50%, 0); }
}
