/* exam.4ab.in — AB EDITORIAL v2 BRIDGE
 * =============================================================================
 * WHY A BRIDGE AND NOT A REWRITE
 * ------------------------------
 * The app's components (.card .btn .chip .inp .tab .stats/.stat .note, plus the
 * chk-/lrn-/tp-/nt-/an-/hw-/ing-/docs-/acct- families) are consumed by twelve
 * pages and twenty scripts. Re-authoring them would risk a working product for
 * a visual change. Instead this file re-declares the PALETTE, the radii, the
 * shadows and the families in AB Editorial v2's values, so the same components
 * render in the AB language, and then adds only the rules that carry AB's
 * character (serif headings, gold hairlines, tinted card groups, the header,
 * the credit bar).
 *
 * IT MUST LOAD LAST (see the note about print.html below).
 * ab-design-system.css sits inside `@layer ab-design-system`, and ANY unlayered
 * declaration beats ANY layered one regardless of specificity — so tokens.css's
 * `:root` would otherwise keep winning and the app would stay on its old
 * blue-grey palette. This file is unlayered and loaded after tokens.css +
 * app.css + the per-page sheet, so it wins.
 *
 * THE TOKEN BLOCK IS ON `:root, .ab-page` — BOTH, DELIBERATELY.
 * The package declares its tokens on `:root, .ab-page` too. Custom properties
 * inherit from the NEAREST declaring ancestor, and cascade layers only rank
 * declarations on the SAME element — so inside <main class="ab-page"> the
 * package's layered `.ab-page` values beat this file's unlayered `:root`
 * values, because <main> is nearer than <html>. Declaring on `:root, .ab-page`
 * here (unlayered, later) is what makes one palette hold in and out of <main>.
 * Getting this wrong is invisible outside <main> and wrong inside it — which
 * is exactly where the whole app lives.
 *
 * ONE EXCEPTION IS DELIBERATE: print.html loads this file BEFORE print.css.
 * print.css is 100% wrapped in `@media print` and re-points every token at
 * black-on-white for the printer. Its token override uses a four-arm selector
 * list whose first arm is a bare `:root` (0,1,0) — a later unlayered `:root`
 * here would out-rank that arm and put colour back into the printout. Loading
 * this file first keeps the printer sheet last where it matters, and costs
 * nothing on screen because print.css never touches the screen medium.
 *
 * WHAT DELIBERATELY DOES NOT CHANGE
 * ---------------------------------
 * `--crop-bg` stays #FFFFFF in both themes. A crop is a photograph of a white
 * printed page; a dark backing frames it with a hard bright edge. That was a
 * deliberate call in tokens.css and it still is.
 * `--green` / `--red` / `--amber` stay SEMANTIC (right / wrong / warning) and
 * are given AA-contrast values here — the package's brand `--green` (#61CE70)
 * measures 1.99:1 on white and would silently make every "correct answer"
 * label unreadable the moment <main class="ab-page"> re-pointed it.
 * =========================================================================== */

/* ============================================================ 1. THE PALETTE
   Three states, token-for-token identical in the two dark blocks (rulebook §8).
   A token defined in one dark block and not the other is correct via the
   toggle and wrong via the OS setting — invisible on the machine you build on.
   The media guard is `:not([data-theme="light"])`, never `:not([data-theme])`:
   this site represents "system" as the ABSENCE of the attribute, so the OS
   query has to keep matching when no attribute is set.                       */

:root, .ab-page {
  /* -- AB brand constants (never themed) -- */
  --gold: #C9A84C;
  --gold-soft: #E8D9AE;
  --gold-ring: #D4A84B;
  --panel-1: #1B2A5E;
  --panel-2: #131E45;
  --navy-deep: #131E45;

  /* -- AB themed surfaces (the package's own names) -- */
  --page-bg: #FFFFFF;
  --card: #FFFFFF;
  --paper: #FAF9F6;
  --line: #E7E2D6;
  --line-soft: #F0EDE4;
  --hair: #E4E7EE;
  --hair-gold: rgba(201, 168, 76, .45);
  --ink: #1C2130;
  --body-c: #3A4152;
  --muted: #6B7280;
  --navy: #1B2A5E;
  --nav-c: #6F6F6F;
  --gold-ink: #8A6D1F;      /* 4.90:1 on white — gold as TYPE */
  --green-ink: #177A39;     /* 5.41:1 on white */
  --body-bg: var(--page-bg);
  --card-surface: var(--card);
  --tint: rgba(201, 168, 76, .14);
  --sheen: rgba(201, 168, 76, .05);
  --focus-ring: var(--gold-ink);

  /* -- the app's own token names, re-pointed at the AB palette -- */
  --bg:      #FAF9F6;       /* the editorial off-white ground */
  --card-2:  #FAF9F6;       /* the app's "second surface" (inputs, .stat, .ans) */
  --line-2:  #F0EDE4;
  --body:    #3A4152;
  --navy-2:  #2C4390;
  --on-navy: #FFFFFF;
  --crop-bg: #FFFFFF;       /* unchanged, on purpose — see the header note */

  /* Semantic state colours. AA on the surface they label, in both themes.
     These are NOT the package's decorative --green; see the header note. */
  --green: #177A39;
  --red:   #C0332B;
  --amber: #96690C;

  --chip-bg:   rgba(27, 42, 94, .06);
  --chip-line: rgba(201, 168, 76, .34);
  --chip-ink-warn: #6E5514;   /* gold ink measured THROUGH the chip's own wash */
  --muted-on-tint: #565D6D;   /* --muted, taken down until it clears 4.5:1 ON a tint */
  --focus:     #8A6D1F;

  /* -- radii: the AB scale (10 / 18 / 26) -- */
  --r-sm: 10px;
  --r-md: 18px;
  --r-lg: 26px;
  --radius: var(--r-md);

  /* -- shadows -- */
  --shadow-soft: 0 10px 30px rgba(27, 42, 94, .10);
  --shadow-lift: 0 18px 45px rgba(27, 42, 94, .16);
  --shadow-sm:   0 10px 30px rgba(27, 42, 94, .08);
  --shadow-md:   0 18px 45px rgba(27, 42, 94, .14);

  /* -- families. The app's --serif/--sans/--mono are mapped onto AB's. -- */
  --font-brand:   'Poppins', system-ui, -apple-system, 'Segoe UI', Arial, sans-serif;
  --font-nav:     'Roboto', system-ui, -apple-system, 'Segoe UI', Arial, sans-serif;
  --font-display: Georgia, 'Times New Roman', Times, serif;
  --font-body:    system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
  --font-mono:    ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, 'Liberation Mono', monospace;
  --serif: var(--font-display);
  --sans:  var(--font-body);
  --mono:  var(--font-mono);

  /* The bank browser is a data-dense tool: the 288px filter rail plus the
     result column earn the extra width, so the app keeps its own 1500px
     measure rather than the portfolio's 1360px. One width for header,
     content and credit bar, so nothing steps. */
  --wrap: 1500px;
}

/* ---- dark, route A: the OS setting (unless the page explicitly asks light) */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]), :root:not([data-theme="light"]) .ab-page {
    --page-bg: #050914;
    --card:    #0D1424;
    --paper:   #0A101E;
    --line:      rgba(148, 163, 184, .18);
    --line-soft: rgba(148, 163, 184, .10);
    --hair:      rgba(148, 163, 184, .16);
    --hair-gold: rgba(245, 185, 66, .40);
    --ink:     #F8FAFC;
    --body-c:  #B9C5D8;
    --muted:   #AEBBD0;
    --navy:    #E2E8F0;
    --nav-c:   #AEBBD0;
    --gold-ink:  #F5B942;
    --green-ink: #10B981;
    --body-bg:
      radial-gradient(circle at 50% -15%, rgba(37, 99, 235, .18), transparent 34%),
      radial-gradient(circle at 100% 85%, rgba(6, 182, 212, .12), transparent 28%),
      linear-gradient(180deg, #050914, #060B17 55%, #040811) #050914;
    --card-surface: linear-gradient(145deg, rgba(17, 24, 39, .98), rgba(8, 13, 24, .98)) #0D1424;

    --bg:      #050914;
    --card-2:  #131B2F;
    --line-2:  rgba(148, 163, 184, .10);
    --body:    #B9C5D8;
    --navy-2:  #A9C0EA;
    --on-navy: #050914;
    --crop-bg: #FFFFFF;

    --green: #34D399;
    --red:   #F87171;
    --amber: #FBBF24;

    --chip-bg:   rgba(226, 232, 240, .07);
    --chip-line: rgba(245, 185, 66, .30);
    --chip-ink-warn: #FBBF24;
    --muted-on-tint: #AEBBD0;
    --focus:     #F5B942;

    --shadow-soft: 0 22px 60px rgba(0, 0, 0, .30);
    --shadow-lift: 0 30px 75px rgba(0, 0, 0, .45);
    --shadow-sm:   0 12px 34px rgba(0, 0, 0, .28);
    --shadow-md:   0 22px 60px rgba(0, 0, 0, .40);
  }
}

/* ---- dark, route B: the explicit toggle. Identical to route A. ---- */
:root[data-theme="dark"], :root[data-theme="dark"] .ab-page {
  --page-bg: #050914;
  --card:    #0D1424;
  --paper:   #0A101E;
  --line:      rgba(148, 163, 184, .18);
  --line-soft: rgba(148, 163, 184, .10);
  --hair:      rgba(148, 163, 184, .16);
  --hair-gold: rgba(245, 185, 66, .40);
  --ink:     #F8FAFC;
  --body-c:  #B9C5D8;
  --muted:   #AEBBD0;
  --navy:    #E2E8F0;
  --nav-c:   #AEBBD0;
  --gold-ink:  #F5B942;
  --green-ink: #10B981;
  --body-bg:
    radial-gradient(circle at 50% -15%, rgba(37, 99, 235, .18), transparent 34%),
    radial-gradient(circle at 100% 85%, rgba(6, 182, 212, .12), transparent 28%),
    linear-gradient(180deg, #050914, #060B17 55%, #040811) #050914;
  --card-surface: linear-gradient(145deg, rgba(17, 24, 39, .98), rgba(8, 13, 24, .98)) #0D1424;

  --bg:      #050914;
  --card-2:  #131B2F;
  --line-2:  rgba(148, 163, 184, .10);
  --body:    #B9C5D8;
  --navy-2:  #A9C0EA;
  --on-navy: #050914;
  --crop-bg: #FFFFFF;

  --green: #34D399;
  --red:   #F87171;
  --amber: #FBBF24;

  --chip-bg:   rgba(226, 232, 240, .07);
  --chip-line: rgba(245, 185, 66, .30);
  --chip-ink-warn: #FBBF24;
  --muted-on-tint: #AEBBD0;
  --focus:     #F5B942;

  --shadow-soft: 0 22px 60px rgba(0, 0, 0, .30);
  --shadow-lift: 0 30px 75px rgba(0, 0, 0, .45);
  --shadow-sm:   0 12px 34px rgba(0, 0, 0, .28);
  --shadow-md:   0 22px 60px rgba(0, 0, 0, .40);
}

/* `color-scheme` mirrors the same three states so native UI (scrollbars, form
   controls, focus rings) matches the painted theme in all three. */
:root { color-scheme: light; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { color-scheme: dark; } }
:root[data-theme="dark"] { color-scheme: dark; }


/* ==================================================== 2. THE PAGE GROUND
   The editorial ground is the off-white/deep-blue-black body; <main> is
   transparent so the ground runs edge to edge behind the content column,
   instead of the package's default white plank on off-white.                */

body {
  background: var(--body-bg);
  background-attachment: fixed;
  color: var(--body);
  font-family: var(--font-body);
}
.ab-page { background: transparent; }

/* Headings take AB's serif at weight 400 — the serif carries the weight, never
   bold. COLOUR IS DELIBERATELY NOT SET HERE: tokens.css already ships an
   unlayered `h1,h2,h3,h4{color:var(--ink)}`, and since ANY unlayered rule beats
   the whole layered package, that reset silently repaints the heading inside
   every permanently-dark AB panel — a navy title on a navy hero. Restating the
   colour here would not have fixed it, only moved it. The dark surfaces get
   their inks back explicitly in §5 and §6b instead. */
h1, h2, h3, h4 { font-family: var(--font-display); font-weight: 400; }
b, strong { font-weight: 700; }

/* Rule 8's companion: the shared visitor counter is hidden site-wide; the
   numbers still collect server-side. Harmless where the widget is absent. */
#ab-visitor-counter { display: none !important; }


/* ================================================ 3. THE PACKAGE'S OWN BUGS
   Fixed HERE, never inside ab-design-system.css — the package is shared with
   every other site and an edit there has to be re-verified on all of them.

   BUG 1 (measured on bpsugar, ROUND 2): `.ab-base a, .ab-page a{color:var(--navy)}`
   is (0,1,1); the button variants' own colours are (0,1,0). So the link reset
   wins on every <a> that is a button — navy text on a navy panel, invisible.  */
.ab-page a.ab-btn--gold,
.ab-page a.ab-btn--navy,
.ab-page a.ab-btn--ghost { color: #FFFFFF; }
.ab-page a.ab-btn--ghost:hover,
.ab-page a.ab-btn--ghost:focus-visible { color: var(--gold-soft); }
.ab-page a.ab-btn--line { color: var(--navy); }
.ab-page a.ab-btn--line:hover,
.ab-page a.ab-btn--line:focus-visible { color: var(--navy); }
.ab-credit a.ab-credit__site { color: #E9C25F; }
.ab-credit a.ab-credit__site:hover,
.ab-credit a.ab-credit__site:focus-visible { color: #F7E7B2; }

/* BUG 2: the package's three-SVG toggle swaps icons on [data-theme="system"].
   This site represents "system" as the ABSENCE of data-theme (tokens.css's
   media query depends on that), so the system icon would never show. */
:root:not([data-theme]) .theme-toggle .ti-light { display: none; }
:root:not([data-theme]) .theme-toggle .ti-system { display: block; }


/* ============================================================== 4. THE HEADER
   The package's .site-header is a 112px portfolio masthead with a 62px
   monogram. This is a working tool that is used all day, so the same component
   is compacted here rather than replaced — every nav, drawer, hue and hover
   rule in the package keeps applying unchanged.                              */

.site-header {
  position: sticky;
  top: 0;
  z-index: 60;
  background: var(--card);
  border-bottom: 1px solid var(--line);
  box-shadow: 0 1px 0 rgba(27, 42, 94, .04);
}
.site-header__inner {
  max-width: var(--wrap);
  min-height: 0;
  padding: 9px 18px;
  gap: 16px;
}
.site-brand { gap: 10px; }
.site-brand__mark {
  width: 36px;
  height: 36px;
  border-radius: 10px;
  display: grid;
  place-items: center;
  background: var(--deep-navy-grad);
  color: var(--gold);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 16px;
  line-height: 1;
}
.site-brand__name { font-size: 17px; }
/* MEASURED: the package sets `.site-brand__name b { color: var(--gold) }`, and
   brand gold on this light header measures 2.29:1 — the exact violation the
   rulebook's palette section exists to prevent ("gold NEVER carries text on a
   light surface"). The header is a light surface, so the brand's second word
   takes the audited ink instead. */
.site-brand__name b { color: var(--gold-ink); }
.site-brand__tagline { font-size: 10.5px; letter-spacing: .05em; text-transform: uppercase; }

/* The nav row is the widest thing in the bar; let it use the space. */
.site-header__inner > .nav { flex: 1 1 auto; }
.nav__link { padding: 11px 9px; font-size: 14px; }

/* The account badge, the total chip and the theme button all live in the
   controls cluster. They are MOVED here by nav.js (never re-created), so
   every listener and every id survives. */
.site-header__controls { gap: 9px; }
.site-header__controls .chip { margin: 0; }
.site-header__controls .acct-badge { font-size: 12.5px; }

/* The app's own theme button is a text glyph, not the package's three SVGs;
   it keeps its markup (and therefore its existing listener) and takes the
   package's circular toggle shape. */
.site-header__controls .iconbtn,
.site-header__controls .icon-btn {
  width: 38px;
  height: 38px;
  flex: 0 0 38px;
  border-radius: 50%;
  border: 1.5px solid var(--line);
  background: var(--card);
  color: var(--navy);
  transition: border-color .2s ease, color .2s ease, transform .2s ease;
}
.site-header__controls .iconbtn:hover,
.site-header__controls .icon-btn:hover {
  border-color: var(--gold);
  color: var(--gold-ink);
  background: var(--card);
  transform: translateY(-1px);
}

@media (max-width: 1239.98px) {
  .site-header__inner { padding: 10px 16px; }
  .site-brand__mark { width: 34px; height: 34px; font-size: 15px; }
}
/* MEASURED at 375px: the controls cluster came out 423px wide and pushed the
   document to 439px — a real horizontal overflow. The package sets
   `.site-header__controls { flex-shrink: 0 }` for a cluster of exactly two
   fixed-width buttons; this app adds the account badge (which carries a
   sign-in button and a "not synced" pill) and the total chip, and a row that
   cannot shrink and cannot wrap can only overflow. It is allowed to wrap
   internally instead — nothing is hidden, because "not synced" is a fact the
   reader needs, not decoration. */
.site-header__controls { flex-wrap: wrap; justify-content: flex-end; row-gap: 6px; min-width: 0; }
#acctBadge { min-width: 0; }
.acct-badge { flex-wrap: wrap; row-gap: 4px; }

@media (max-width: 760px) {
  .site-header__inner { padding: 9px 12px; gap: 8px; }
  .site-header__controls { flex-shrink: 1; }
  .site-brand__mark { width: 32px; height: 32px; font-size: 14px; }
  .site-brand__name { font-size: 15px; }
  .site-brand__tagline { display: none; }
  /* 44px tap targets throughout the header, Rule 7's floor */
  .site-header__controls .iconbtn,
  .site-header__controls .icon-btn { width: 44px; height: 44px; flex: 0 0 44px; }
  .nav-toggle { min-width: 44px; min-height: 44px; }
  .acct-badge__signin, .acct-badge__signout { min-height: 44px; }
}

/* MEASURED at 375px with the drawer open: "Question Paper Analyser" rendered
   155px wide inside its own 110px tile and pushed the document to 385px. The
   package's `.nav__link` is `white-space: nowrap` because the portfolio's menu
   labels are one word each; this product's are four. In the drawer — where a
   tile is a fixed third of the row — the label has to wrap. (Same family as
   the nowrap overflow already recorded against the mega panel.) */
@media (max-width: 1239.98px) {
  .nav__link, .nav__sublink { min-height: 108px; white-space: normal; }
  .nav__link > span, .nav__sublink > span { white-space: normal; }
}

/* 2026-09-04 — the package's R7 "tapped-open tile turns its own hue" rule is
   only defined for drawer positions 2-6 (it was written for one "More" tile
   that could never be position 1). The 5-category menu makes "Question Bank"
   position 1, and an undefined nth-child(1).is-open left its open tile in
   the default ink instead of a hue — every OTHER open category tile visibly
   recolours, so a silent exception on the very first one reads as broken,
   not deliberate. Matches item 1's own resting-state stroke colour
   (var(--hue-green), set by the package two rules above its drawer block)
   so the open state is simply that same hue, filled in, like its siblings. */
@media (max-width: 1239.98px) {
  .nav__list > .nav__item:nth-child(1).is-open > .nav__link { color: var(--hue-green); border-color: var(--hue-green); }
  .nav__list > .nav__item:nth-child(1).is-open > .nav__link .nav__icon { background: var(--hue-green); }
}

/* MEASURED BUG, 2026-09-04: nav.js renders Institute with the `hidden`
   attribute for a guest/student, but the package's drawer rule
   `.nav__item { display: contents }` is an explicit `display` declaration
   that OVERRIDES the browser's own `[hidden] { display: none }` UA rule —
   author CSS beats user-agent CSS regardless of specificity. Below 1240px
   the Institute tile therefore rendered anyway, `hidden` attribute or not;
   at desktop width `.nav__item` sets no `display` at all, so `[hidden]`
   worked there untouched, which is what hid the bug in a desktop-only check.
   This file is unlayered, so it beats the package's `@layer` rule outright —
   no !important needed, just stating `display: none` for this one case. */
.nav__item--institute[hidden] { display: none; }


/* ====================================================== 5. THE PAGE MASTHEAD
   The compact hero recipe (rulebook §6): centred, ~40% of the full hero,
   ONE gold glow, a symmetric kicker rule. Never the full navy hero on a
   tool page — the tool has to start above the fold.                         */

/* MEASURED 2026-09-12: `margin: 18px 0 4px` set the side margins to 0, which
   overrode `.ab-wrap`'s own `auto` centring — so the hero was LEFT-PINNED while
   `main.wrap` and `.ex-tabs` stay centred (`app.css:45`, `margin: 0 auto`). At
   1920 the hero spanned 24→1476 while the content spanned 220→1684; at 1440 it
   was 6px out on each side, because `.ab-wrap` pads 24px and `.wrap` pads 18px.
   `auto` restores the centring this rule's own comment says it wants, and the
   18px matches `.wrap` so the hero, the tabs, the sidebar and the results all
   share one left edge. Shorthand `margin` is kept — a bare `margin-inline`
   would lose to `.ab-wrap`'s shorthand in the layer cascade. */
.ex-hero { margin: 18px auto 4px; padding-inline: 18px; }
.ex-hero .ab-hero__panel {
  text-align: center;
  padding: clamp(20px, 3.2vw, 34px) clamp(22px, 6vw, 72px);
  background:
    radial-gradient(720px 300px at 50% -35%, rgba(201, 168, 76, .38), transparent 62%),
    var(--deep-navy-grad);
  border-radius: var(--r-lg);
}
.ex-hero .ab-kicker::after {
  content: "";
  width: 34px;
  height: 1.5px;
  background: var(--gold);
  display: inline-block;
  vertical-align: middle;
  margin-left: 10px;
}
/* The panel is permanently dark in BOTH themes, so its inks are literals and
   `--ink` / `--navy` are never used here — both are themed and would flip to a
   near-white in dark mode and to a near-black on this navy in light mode. */
.ex-hero .ab-hero__title {
  font-size: clamp(24px, 3.4vw, 36px);
  margin: 0 0 8px;
  line-height: 1.15;
  color: #FFFFFF;
}
.ex-hero .ab-kicker { color: var(--gold-soft); }
.ex-hero .ab-hero__lede {
  margin: 0 auto;
  max-width: 78ch;
  font-size: var(--fs-1);
  text-align: center;
  text-wrap: pretty;
  color: #D8DFF0;
}
@media (max-width: 640px) {
  .ex-hero { margin-top: 12px; }
  .ex-hero .ab-hero__panel { padding: 20px 18px; }
}


/* ==================================================== 6. THE APP COMPONENTS
   Everything below re-dresses a component the app already ships. No component
   is renamed and no markup contract changes.                                 */

/* -- cards -------------------------------------------------------------- */
.card {
  background: var(--card-surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-soft);
}
.empty h3 { font-family: var(--font-display); }

/* -- buttons ------------------------------------------------------------ */
.btn {
  border-radius: 999px;
  border: 1.5px solid var(--line);
  background: var(--card);
  color: var(--navy);
  font-family: var(--font-nav);
  font-weight: 600;
  font-size: 13.5px;
  letter-spacing: .01em;
  padding: 9px 17px;
  transition: border-color .2s ease, color .2s ease, background .2s ease, transform .2s ease, box-shadow .2s ease;
}
.btn:hover {
  background: var(--card);
  border-color: var(--gold);
  color: var(--navy);
  transform: translateY(-1px);
  box-shadow: 0 8px 22px rgba(201, 168, 76, .22);
}
.btn:active { transform: translateY(0); }
.btn--primary {
  background: var(--deep-navy-grad);
  border-color: transparent;
  color: #FFFFFF;
  text-shadow: 0 1px 2px rgba(0, 0, 0, .35);
}
.btn--primary:hover {
  background: var(--deep-navy-grad);
  border-color: transparent;
  color: #FFFFFF;
  box-shadow: 0 12px 30px rgba(27, 42, 94, .34);
}
.btn[disabled], .btn[disabled]:hover { opacity: .5; transform: none; box-shadow: none; }

/* -- chips -------------------------------------------------------------- */
.chip {
  border-radius: 999px;
  border: 1px solid var(--chip-line);
  background: var(--chip-bg);
  color: var(--navy);
  font-family: var(--font-nav);
  font-weight: 600;
  letter-spacing: .04em;
}
/* A chip's own tint darkens the surface under its 11.5px label, so the ink has
   to be measured against THAT, not against white. --gold-ink is 4.90:1 on
   white but only 4.32:1 once its own 10% wash is under it — a fail at this
   size. --chip-ink-warn is the same hue taken down until it clears 4.5:1 in
   place. Measured, not eyeballed. */
.chip--good { background: rgba(23, 122, 57, .10);  border-color: rgba(23, 122, 57, .32);  color: var(--green-ink); }
.chip--warn { background: rgba(138, 109, 31, .10); border-color: rgba(138, 109, 31, .32); color: var(--chip-ink-warn); }
.chip--bad  { background: rgba(192, 51, 43, .10);  border-color: rgba(192, 51, 43, .32);  color: var(--red); }
/* "asked N×" — a plain FACT about the question (it was printed in more than one
   compilation), not a warning and not a fault, so it takes the same green as
   chip--good rather than the amber the integrity flags use. */
.chip--freq { background: rgba(23, 122, 57, .10);  border-color: rgba(23, 122, 57, .32);  color: var(--green-ink); }

/* -- inputs ------------------------------------------------------------- */
.inp, select.inp, textarea.inp {
  border-radius: var(--r-sm);
  border: 1px solid var(--line);
  background: var(--card);
  font-family: var(--font-body);
}
.inp:focus, select.inp:focus, textarea.inp:focus {
  border-color: var(--gold);
  outline: none;
  box-shadow: 0 0 0 3px rgba(201, 168, 76, .18);
}
.fgroup > label, .fgroup > .flabel {
  font-family: var(--font-mono);
  letter-spacing: var(--track-label);
  color: var(--gold-ink);
}

/* -- the tab rails (app, check, ingest, notes, topic, analyse) ----------- */
.tab, .chk-tab, .ing-tab, .nt-tab, .an-srctab {
  font-family: var(--font-nav);
  font-weight: 600;
  border-radius: 999px;
  color: var(--nav-c);
  letter-spacing: .01em;
  transition: color .18s ease, background .18s ease, border-color .18s ease;
}
.tab:hover, .chk-tab:hover, .ing-tab:hover, .nt-tab:hover, .an-srctab:hover {
  color: var(--navy);
  background: var(--paper);
}
.tab[aria-selected="true"],
.chk-tab[aria-selected="true"],
.ing-tab[aria-selected="true"],
.nt-tab[aria-selected="true"],
.an-srctab[aria-selected="true"] {
  background: var(--deep-navy-grad);
  border-color: transparent;
  color: #FFFFFF;
  text-shadow: 0 1px 2px rgba(0, 0, 0, .35);
}

/* -- figure rows -------------------------------------------------------- */
.stat, .tp-stat, .lrn-rollup {
  border-radius: var(--r-sm);
  border: 1px solid var(--line);
  background: var(--paper);
}
.stat b, .tp-stat b, .lrn-rollup b, .pool b, .chk-score__big {
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
}
.stat span, .tp-stat span, .lrn-rollup span {
  font-family: var(--font-nav);
  letter-spacing: .03em;
  color: var(--muted-on-tint);
}

/* Rule 1 — every card in a group gets a DIFFERENT tint, as CLASSES, cycling.
   The figure rows are generated by JS from live counts, so they cannot carry a
   hand-written class; they are the one place the cycle is expressed
   positionally, and they are deliberately given the tint BACKGROUND only, not
   the interactive hover set — a statistic is not a destination. Every group
   that is a row of real destinations gets real ab-tint-N classes from nav.js
   or from the page markup instead. */
.ab-page .stats > .stat:nth-child(6n+1),
.ab-page .lrn-rollups > .lrn-rollup:nth-child(6n+1) { background: var(--tint-1-bg); border-color: var(--tint-1-line); }
.ab-page .stats > .stat:nth-child(6n+2),
.ab-page .lrn-rollups > .lrn-rollup:nth-child(6n+2) { background: var(--tint-2-bg); border-color: var(--tint-2-line); }
.ab-page .stats > .stat:nth-child(6n+3),
.ab-page .lrn-rollups > .lrn-rollup:nth-child(6n+3) { background: var(--tint-3-bg); border-color: var(--tint-3-line); }
.ab-page .stats > .stat:nth-child(6n+4),
.ab-page .lrn-rollups > .lrn-rollup:nth-child(6n+4) { background: var(--tint-4-bg); border-color: var(--tint-4-line); }
.ab-page .stats > .stat:nth-child(6n+5),
.ab-page .lrn-rollups > .lrn-rollup:nth-child(6n+5) { background: var(--tint-5-bg); border-color: var(--tint-5-line); }
.ab-page .stats > .stat:nth-child(6n+6),
.ab-page .lrn-rollups > .lrn-rollup:nth-child(6n+6) { background: var(--tint-6-bg); border-color: var(--tint-6-line); }

/* -- notes / callouts --------------------------------------------------- */
.note {
  border-radius: var(--r-sm);
  border: 1px solid var(--hair-gold);
  border-left: 4px solid var(--gold);
  background: var(--paper);
  color: var(--body);
}
.note--info { border-left-color: var(--navy-2); color: var(--body); }

/* The honest-limits blocks are this product's conscience — same callout
   treatment everywhere so they read as one voice, never as decoration. */
.chk-honest, .lrn-honest, .ing-honest, .hw-honest, .tp-caveat,
.nt-section__note, .lrn-section__note, .tp-section__note, .an-ai-banner {
  border-radius: var(--r-sm);
  border: 1px solid var(--hair-gold);
  border-left: 4px solid var(--gold);
  background: var(--paper);
  color: var(--body);
}

/* -- question cards ----------------------------------------------------- */
.q, .chk-q, .hw-q, .ing-qcard, .nt-example {
  border-radius: var(--radius);
  border: 1px solid var(--line);
  background: var(--card-surface);
}
.q__no, .chk-q__head .chk-q__marks {
  font-family: var(--font-mono);
  border-radius: 8px;
}
.q__no { background: var(--deep-navy-grad); color: #FFFFFF; }
.q__crop, .chk-crop, .hw-crop, .ing-qcard__crop, .nt-example__crop {
  border-radius: var(--r-sm);
  border: 1px solid var(--line);
}

/* -- panels and sections in the tool pages ------------------------------ */
.chk-panel, .tp-section, .nt-section, .lrn-section, .an-srcpanel, .ing-panel > .card {
  border-radius: var(--radius);
}
.tp-section > h2, .nt-section > h2, .lrn-section > h2, .sec h3, .chk-panel h2 {
  font-family: var(--font-display);
  font-weight: 400;
}

/* -- tables: gold hairline heads, tabular figures ----------------------- */
.chk-table, .tp-table, .lrn-table-wrap table, .an-list table {
  font-variant-numeric: tabular-nums;
}
.chk-table th, .tp-table th, .lrn-table-wrap th, .an-list th {
  font-family: var(--font-nav);
  letter-spacing: .04em;
  text-transform: uppercase;
  font-size: 11.5px;
  color: var(--gold-ink);
  border-bottom: 1px solid var(--hair-gold);
}

/* -- boot ---------------------------------------------------------------- */
#boot, #ntBoot { font-family: var(--font-nav); color: var(--muted); }
#boot .bar2 i, #ntBoot .bar2 i { background: var(--grad-cta); }

/* -- links inside the content column ------------------------------------ */
.ab-page a { color: var(--navy); }
.ab-page a:hover { color: var(--gold-ink); }
/* …but never re-colour a link that is dressed as a button or a tile. */
.ab-page a.btn, .ab-page a.btn:hover { color: var(--navy); }
.ab-page a.btn--primary, .ab-page a.btn--primary:hover { color: #FFFFFF; }
.ab-page a.tab { color: var(--nav-c); }
.ab-page a.tab:hover { color: var(--navy); }
.ab-page a.tab[aria-selected="true"] { color: #FFFFFF; }


/* ================================================ 6b. PAGE-SPECIFIC CHROME
   Three places keep their own markup because a script owns it, and are
   re-dressed here rather than rewritten.                                     */

/* -- app/index.html's view switcher. It is not navigation (the shared menu is
      one row above it); it is the page's three views, so it reads as a rail
      under the hero rather than as a second menu. -- */
.ex-tabs {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin: 16px auto 0;
  padding: 0 18px;
}
.ex-tabs .tab { padding: 9px 18px; border: 1px solid var(--line); }
@media (max-width: 480px) {
  .ex-tabs { gap: 6px; }
  .ex-tabs .tab { flex: 1 1 auto; padding: 11px 10px; text-align: center; }
}

/* -- check.html's own bar. #tbTitle carries the LOADED PAPER's name, which is
      a different thing from the tool name in the hero above it, so both stay.
      Its ids (#top, #tbTitle, #timer) are untouched. -- */
.chk-top {
  max-width: var(--wrap);
  margin: 16px auto 0;
  padding: 14px 18px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--card-surface);
  box-shadow: var(--shadow-soft);
}
.chk-top__title {
  font-family: var(--font-display);
  font-size: var(--fs-3);
  color: var(--ink);
}
.chk-top__sub { color: var(--muted); }
.chk-timer { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }

/* -- print.html's sticky control bar -- */
.toolbar {
  background: var(--card);
  border-bottom: 1px solid var(--line);
}
.toolbar__title { font-family: var(--font-display); }
.paper { border-radius: var(--radius); border-color: var(--line); }

/* -- the landing page. Its markup already has the right anatomy — an eyebrow,
      an h1, a lede, chips and an action row — so the compact hero recipe is
      applied to it rather than a second hero being inserted above its own. -- */
.hero.card {
  border: 0;
  border-radius: var(--r-lg);
  background:
    radial-gradient(720px 300px at 50% -35%, rgba(201, 168, 76, .38), transparent 62%),
    var(--deep-navy-grad);
  padding: clamp(26px, 4vw, 44px) clamp(22px, 5vw, 54px);
  box-shadow: var(--shadow-lift);
}
.hero.card .eyebrow {
  color: var(--gold-soft);
  font-family: var(--font-mono);
  letter-spacing: var(--track-label);
}
.hero.card h1 {
  font-family: var(--font-display);
  font-weight: 400;
  color: #FFFFFF;
}
.hero.card .lead { color: #D8DFF0; }
.hero.card .chip {
  background: rgba(255, 255, 255, .10);
  border-color: rgba(232, 217, 174, .34);
  color: var(--gold-soft);
}
.hero.card .muted { color: #B9C5D8; }
.hero.card .btn--primary { border-color: transparent; }

/* the landing's remaining sections read as AB panels */
.ab-page > .wrap > section.card { border-radius: var(--radius); }
.ab-page .eyebrow {
  font-family: var(--font-mono);
  letter-spacing: var(--track-label);
  color: var(--gold-ink);
}
.ab-page h2, .ab-page h3 { font-family: var(--font-display); font-weight: 400; }
.ab-page thead th {
  background: var(--paper);
  color: var(--gold-ink);
  border-bottom: 1px solid var(--hair-gold);
}
.ab-page .bar i { background: var(--grad-primary); }
.ab-page .bar i.alt { background: linear-gradient(90deg, #0D9488, #2DD4BF); }
.ab-page .bar i.gold { background: var(--grad-cta); }
.ab-page .tablebox { border-radius: var(--radius); }
footer > .foot { border-top: 0; }


/* ===================================================== 7. THE CREDIT BAR (R8)
   One component, every page, `V.n` bumped on every deploy by _build/ab-stamp.js.
   .ab-credit is permanently dark in BOTH themes, so its inks are literals —
   never --navy, which is themed and flips to a pale grey in dark mode.       */
footer.ab-credit {
  margin-top: 46px;
  background: var(--deep-navy-grad);
  border-top: 0;
  padding: 18px;
}
.ab-credit__mid { font-variant-numeric: tabular-nums; }


/* ============================================================== 8. PRINTING
   check / print / notes / analyse / homework all print. The bridge must add
   NOTHING to paper: no tints, no navy panels, no gold — those either vanish
   (browsers strip backgrounds by default) or waste toner.                    */
@media print {
  /* THE ONE THAT NEARLY SHIPPED WRONG.
     print.css keeps the theme out of the printer by re-pointing the tokens on
     `:root` — and says so, because a teacher with dark mode on must not get a
     dark-grey page that empties a toner cartridge. But print.html's <main> now
     carries `.ab-page`, and §1 above declares the whole palette on `.ab-page`
     as well as on `:root`. Custom properties resolve from the NEAREST declaring
     ancestor, so inside <main> — which is the entire printed paper — this
     file's screen palette would have beaten print.css's override, and the paper
     would have printed navy, gold and tinted. The reset below hands the
     printer's own values straight back, on the same element, so nothing on the
     page can out-reach it. Values mirror print.css's block exactly; the AB-only
     token names it has never heard of are added.

     SCOPED to the two pages whose own stylesheet asks for a monochrome
     printout — print.html (the paper) and topic.html (the revision sheet).
     check / homework / analyse / notes deliberately keep their printed colour:
     .chk-status--correct and --wrong are green and red TEXT, and that is the
     signal a teacher reads down a marked script. Browsers drop backgrounds
     from a printout but keep text colour, so forcing those to black would
     remove meaning, not toner. */
  .ex-p-print .ab-page,
  .ex-p-topic .ab-page {
    --bg: #fff; --page-bg: #fff; --body-bg: #fff;
    --card: #fff; --card-2: #fff; --paper: #fff; --card-surface: #fff;
    --crop-bg: #fff;
    --line: #000; --line-2: #999; --line-soft: #999;
    --hair: #999; --hair-gold: #999;
    --ink: #000; --body: #000; --body-c: #000; --muted: #333;
    --navy: #000; --navy-2: #000; --nav-c: #333;
    --gold: #000; --gold-ink: #000; --gold-soft: #000;
    --green: #000; --green-ink: #000; --red: #000; --amber: #000;
    --chip-ink-warn: #000; --muted-on-tint: #333;
    --on-navy: #fff;
    --chip-bg: transparent; --chip-line: #000;
    --shadow-sm: none; --shadow-md: none;
    --shadow-soft: none; --shadow-lift: none;
    --deep-navy-grad: none;
    --tint-1-bg: none; --tint-2-bg: none; --tint-3-bg: none;
    --tint-4-bg: none; --tint-5-bg: none; --tint-6-bg: none;
    --tint-1-line: #999; --tint-2-line: #999; --tint-3-line: #999;
    --tint-4-line: #999; --tint-5-line: #999; --tint-6-line: #999;
  }

  .site-header, #abNav, .ab-credit, .nav, .nav-toggle, .theme-toggle,
  .ex-hero, .ex-tabs { display: none !important; }

  /* MEASURED on the print canary: 24 elements inside the paper still printed
     #3A4152. Their `color` is inherited from <body>, and this file's own
     `body { color: var(--body) }` sits LATER than print.css's
     `@media print html,body { color:#000 }` at equal specificity — a media
     query adds no specificity, so source order decided it and the screen ink
     won on paper. Restated here, inside the print block, where it belongs.
     Children with a colour of their own still keep it, which is what leaves
     .chk-status--correct / --wrong green and red on a marked script. */
  body { background: #FFFFFF !important; color: #000 !important; }
  .ab-page { background: transparent !important; }

  .ab-page .stats > .stat,
  .ab-page .lrn-rollups > .lrn-rollup,
  .card, .q, .chk-q, .hw-q, .ing-qcard, .nt-example, .stat, .note,
  .chk-honest, .lrn-honest, .ing-honest, .hw-honest, .tp-caveat {
    background: transparent !important;
    box-shadow: none !important;
  }
  .btn, .btn--primary, .chip,
  .tab[aria-selected="true"], .chk-tab[aria-selected="true"],
  .ing-tab[aria-selected="true"], .nt-tab[aria-selected="true"] {
    background: transparent !important;
    color: #000 !important;
    text-shadow: none !important;
    box-shadow: none !important;
  }
  .q__no { background: transparent !important; color: #000 !important; }
}


/* ====================================================== 9. REDUCED MOTION
   The package already ships the site-wide kill-switch; this only opts the
   two transforms added above out of it, scoped, per the rulebook's contract
   that page CSS must not ship its own unscoped kill-switch.                  */
@media (prefers-reduced-motion: reduce) {
  .btn:hover,
  .site-header__controls .iconbtn:hover,
  .site-header__controls .icon-btn:hover { transform: none; }
}

/* ==================================================== 10. HEADER SEARCH BOX
   2026-09-06 [Sonnet·question-search] — D3: a compact "search the question
   bank" box in the shared header (nav.js), on every page including /q/ and
   /search/ itself. Free, no login: it is a plain GET form to /search/. Sits
   in the controls cluster, before the hamburger — .site-header__controls
   already flex-wraps (see rule 7 above) so this never breaks the bar.       */
.nav-search {
  display: flex; align-items: center; gap: 0;
  border: 1px solid var(--line-2, #d8dce3); border-radius: 999px;
  background: var(--card, #fff); overflow: hidden; flex: none;
  height: 34px;
}
.nav-search__input {
  border: 0; background: transparent; padding: 0 4px 0 12px;
  font-size: 13px; width: 132px; min-width: 0; outline: none;
}
.nav-search__input::placeholder { color: var(--muted, #7a8296); }
.nav-search__btn {
  border: 0; background: transparent; cursor: pointer; flex: none;
  width: 34px; height: 34px; display: flex; align-items: center; justify-content: center;
  color: var(--muted, #7a8296);
}
.nav-search__btn:hover { color: var(--navy, #1b2a5e); }
.nav-search__icon { width: 16px; height: 16px; }
@media (max-width: 520px) {
  .nav-search__input { width: 92px; }
}

/* =========================================================== 4c. ONE-ROW HEADER
   Owner 2026-09-13 ("iska ui ux thik karo", screenshot signed in as Owner).
   MEASURED at 1820 with a signed-in owner: header 98px, "Institute" on a second
   row, and the account badge + theme toggle on a third. Two causes, both fixed
   here:
     1. `.site-header__inner` is capped at --wrap (1500px) even on an 1820px
        screen — the console below it is 1700px wide, so the bar was NARROWER
        than the page it sits over and had no room for the 6th item.
     2. At 1440 there genuinely is not room at 14px/9px padding: the nav needs
        ~860px for six items and only ~655px is free once the brand, the search
        box and the owner badge have taken theirs.
   So: let the bar use the real width, and compact the links + controls. Desktop
   only — below 1240px the package's Rule-7 drawer takes over untouched, and the
   375px wrap fix above (which exists to stop a real overflow) must keep its
   `flex-wrap: wrap`, hence the min-width guard on the nowrap here.          */
@media (min-width: 1240px) {
  .site-header__inner { max-width: 1740px; gap: 12px; }
  .site-header__inner > .nav .nav__list { flex-wrap: nowrap; }
  .nav__list > .nav__item > .nav__link {
    padding: 8px 9px; font-size: 13.5px; gap: 6px; border-radius: 999px;
    transition: background .15s, color .15s;
  }
  .nav__list > .nav__item > .nav__link:hover { background: var(--chip-bg); }
  /* The section you are in, as a soft pill — the package only changes the ink,
     which is easy to miss on a bar this dense. */
  .nav__list > .nav__item.is-current > .nav__link,
  .nav__list > .nav__item > .nav__link[aria-current="page"] {
    background: rgba(37, 99, 235, .10); color: #1D4ED8;
  }
  .nav__list > .nav__item.is-current > .nav__link .nav__icon { stroke: #1D4ED8; opacity: 1; }
  .nav__caret { width: 12px; height: 12px; margin-left: -2px; }
  .site-header__controls { gap: 8px; flex-wrap: nowrap; }
  .nav-search__input { width: 104px; }
  .site-header__controls .acct-badge { font-size: 12px; flex-wrap: nowrap; white-space: nowrap; }
  .site-header__controls .acct-badge .btn { min-height: 32px; padding: 0 12px; font-size: 12.5px; }
}
@media (min-width: 1240px) and (max-width: 1560px) {
  .site-brand__tagline { display: none; }
  .nav__list > .nav__item > .nav__link { padding: 7px 7px; font-size: 12.8px; }
  .nav__icon { width: 15px; height: 15px; }
  .nav-search__input { width: 84px; }
  .site-header__controls .acct-badge__credits { display: none; }  /* the wallet chip is on /app/admin.html too */
}
/* The owner badge must be allowed to give way — MEASURED at 1280 signed in:
   it ran 39px past the viewport once the row could not wrap. Nothing is
   hidden that cannot be read elsewhere: the wallet total is on /app/admin.html
   and the role is on the account menu. */
@media (min-width: 1240px) {
  .site-header__controls > * { min-width: 0; }
  .site-header__controls .acct-badge { min-width: 0; }
  .acct-badge__who { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
  .acct-badge__signout, .acct-badge__signin { flex: 0 0 auto; }
}
@media (min-width: 1240px) and (max-width: 1420px) {
  .acct-badge__role { display: none; }
  .acct-badge__who { max-width: 14ch; }
  .nav-search__input { width: 72px; }
}

/* ===================================================================
   STICKY MENU (owner 2026-09-13: "menu ko sticky bana do")

   .site-header ALREADY declared position:sticky; top:0 — and it never worked
   on any page. nav.js mounts the header inside <div id="abNav">, and that div
   holds nothing else, so it is exactly as tall as the header (57px measured).
   A sticky element is bounded by its CONTAINING BLOCK, so the header had 0px
   of travel and scrolled away with the wrapper: measured top -600 after a
   600px scroll.

   So the fix is to stick the WRAPPER, whose containing block is <body> and
   therefore the whole page. The header's own sticky rule is left in place and
   is now simply inert — harmless, and removing it would only invite someone to
   "restore" it later without knowing why it could never work.
   =================================================================== */
#abNav {
  position: sticky;
  top: 0;
  z-index: 60;   /* same layer the header asked for, now on the element that moves */
}

/* The drawer and the mega panels are positioned inside the header, so the
   wrapper must not clip them once it becomes the positioned ancestor. */
#abNav { overflow: visible; }

/* The longer name ("ABC AI Questions Maker + Checker" is 341px against the old
   "ABC Question Bank" at ~200px) pushed the header to 75px and put 4px of
   horizontal overflow on the page at 1440. The name is the thing that grew, so
   the name is what gives the space back — the nav keeps its row. */
@media (min-width: 1240px) {
  .site-brand { flex: 0 1 auto; min-width: 0; }
  .site-brand__name { font-size: 15px; white-space: nowrap; }
  /* Two lines of branding is one too many once the name itself says what the
     site does; the tagline was repeating the point in smaller type. */
  .site-brand__tagline { display: none; }
}

/* Two-line brand, as the owner wrote the name. The <b> becomes its own line,
   so the existing light/bold split still does the styling. nowrap is dropped —
   it was what let the one-line version paint over the first menu item instead
   of simply being too wide. */
.site-brand__name { white-space: normal; line-height: 1.12; }
.site-brand__name b { display: block; }
@media (min-width: 1240px) { .site-brand__name { font-size: 14.5px; } }

/* ===================================================================
   TWO-LINE HEADER (owner 2026-09-13: "menu ko do line mein karo and menu
   improve karo")

   His signed-in screenshot was the argument for it: brand wrapped to four
   lines, the search box squeezed to about half a word, and "Sign out" clipped
   at the right edge — because brand, account cluster and nine menu items were
   all competing for one row.

   Splitting by JOB rather than by overflow:
     line 1  who you are  — brand, search, account, theme
     line 2  where to go  — the menu, across the full width

   The markup already runs brand -> controls -> nav, so this is wrap plus one
   full-width basis on the nav. No DOM change, so the mobile drawer below
   1240px is untouched.
   =================================================================== */
@media (min-width: 1240px) {
  .site-header__inner {
    flex-wrap: wrap;
    align-items: center;
    row-gap: 4px;
    padding-top: 8px;
    padding-bottom: 4px;
  }

  /* Line 1: brand left, everything else pushed right. */
  .site-header__inner > .site-brand      { order: 1; }
  .site-header__inner > .site-header__controls { order: 2; margin-left: auto; }

  /* Line 2: the menu gets the whole width to itself. */
  .site-header__inner > .nav {
    order: 3;
    flex: 1 0 100%;
    min-width: 0;
  }
  .nav__list {
    justify-content: flex-start;
    gap: 2px;
    flex-wrap: wrap;      /* a narrow window wraps rather than clipping */
  }

  /* With a row of its own the items can breathe again — the cramped 13.5px
     pills were a symptom of sharing the row, not a choice. */
  .nav__link { font-size: 14px; padding: 6px 11px; }

  /* The search box was the first thing to collapse when space ran out; on its
     own line-1 it can hold a real query again. */
  .nav-search input, .nav-search__input { min-width: 180px; }

  /* The name reads on one line now that it is not fighting the menu for room. */
  .site-brand__name { font-size: 15px; }
  .site-brand__name b { display: inline; }
}

/* ===================================================================
   THE MENU: TWO CENTRED ROWS (owner 2026-09-13: "split this into two parts,
   keep in centre and two rows")

   Row 1 — what the site DOES: bank, the two makers, the checker, Learn,
           and Institute for staff.
   Row 2 — what you REACH FOR while doing it: the four standalone tools.

   The break is declared in the DATA (row: 2 in nav.js), not left to flex-wrap,
   so the split cannot drift when a label changes length or Institute appears
   for a signed-in teacher.

   SPECIFICITY: written as .nav__list > li.nav__break (0,2,1). A bare
   .nav__break (0,1,0) lost to the package's own .nav__list > .nav__item rules
   and the li kept display:list-item — measured, and the reason the first
   attempt rendered all nine items on one row.
   =================================================================== */
.nav__list > li.nav__break { display: none; }

@media (min-width: 1240px) {
  /* Centre both rows. */
  .nav__list {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    gap: 2px 4px;
  }

  /* The forced break: a zero-height full-width item, so the four tools always
     start a new line no matter how much room is left on the first. */
  .nav__list > li.nav__break {
    display: block;
    flex: 1 0 100%;
    width: 100%;
    height: 0;
    margin: 3px 0 0;
    padding: 0;
    border-top: 1px solid rgba(27, 42, 94, .08);
  }
}

/* ===================================================================
   CORRECTIONS to the two earlier attempts in this file. Both were written for
   a ONE-ROW header and actively prevent the two-row one the owner asked for.

   1. `.site-header__inner > .nav .nav__list { flex-wrap: nowrap }` (line ~963,
      added this morning to keep everything on a single row) is (0,3,0) and beat
      the (0,1,0) wrap rule above — measured: all nine items on one line with
      532px of the menu hanging off the left of the page. Same specificity here,
      later in the file, so this one wins.

   2. `.site-brand__name b { display: inline }` was part of the two-line-header
      block and undid the two-line NAME. The owner wants the name as he wrote
      it — "ABC AI Questions" over "Maker + Checker" — so the <b> is a block
      again, and the nowrap that once forced it onto one line is dropped.
   =================================================================== */
@media (min-width: 1240px) {
  .site-header__inner > .nav .nav__list {
    flex-wrap: wrap;
    justify-content: center;
  }

  /* "Maker + Checker" on its own line, per the owner's own spelling of the name. */
  .site-brand__name       { white-space: normal; line-height: 1.14; }
  .site-brand__name b     { display: block; }
}

/* ===================================================================
   THE WHOLE HEADER IS TWO ROWS, NOT THREE (owner 2026-09-13:
   "sare ko do row mein hi fix karo, 3 main nahi")

   The previous block gave the menu a full-width line of its own, which made
   the header brand-line + menu-line-1 + menu-line-2 = three. The owner counts
   the header, and he is right to: the brand occupies about 220px on the left
   and the account cluster about 500px on the right, so the middle of row 1 was
   sitting empty while the menu queued underneath it.

   So the menu moves INTO row 1, between the two, and only its own second line
   (the four tools, forced by li.nav__break) falls to row 2:

     row 1   brand | Question Bank · AI Test Generator · AI Notes Maker ·
                     AI Answer Checking · Learn | search · account · theme
     row 2   Structure editor · Periodic Table · Calculator · Whiteboard
             (· Institute, when signed in as staff)

   Measured before committing to it: menu row 1 is 643px wide, and the gap
   between brand and controls is ~720px at 1440 and ~1180px at 1900 — so it
   fits at both, with the wrap still there as the safety net if a future label
   grows.
   =================================================================== */
@media (min-width: 1240px) {
  .site-header__inner > .site-brand { order: 1; }

  /* No longer a full-width line — it shares row 1 and takes what is left. */
  .site-header__inner > .nav {
    order: 2;
    flex: 1 1 auto;
    min-width: 0;
    margin-left: 12px;
  }

  .site-header__inner > .site-header__controls {
    order: 3;
    margin-left: auto;   /* still pinned to the right edge of row 1 */
  }

  /* Row 2 is the nav's own second line, so it centres within the nav's box. */
  .site-header__inner > .nav .nav__list { justify-content: center; }
}

/* ===================================================================
   THE RIGHT-HAND CLUSTER IS TWO ROWS TOO (owner 2026-09-13:
   "isko bhi split karke 2 row mein karo and right mein rakho")

   Simulated signed-in as Owner at 1900px — Institute visible, the real
   "Aniket Bhardwaj · Owner · ₹484.70" badge and Sign out in place — and the
   header was STILL three rows: search + account + theme could not fit beside
   the menu, so the whole cluster wrapped onto a line of its own (measured at
   top 86 while the menu sat at 8 and 49). Signed out it fitted, which is why
   it looked finished and was not.

   Splitting the cluster the same way the menu was split gives a header that is
   two rows for a signed-in owner as well:

     row 1   brand | menu line 1            | search
     row 2           menu line 2            | account · Sign out · theme

   Both halves of the cluster stay hard right, so the eye still finds the
   account where it has always been.
   =================================================================== */
@media (min-width: 1240px) {
  .site-header__controls {
    flex-wrap: wrap;
    justify-content: flex-end;   /* keep it right, as asked */
    align-items: center;
    align-content: center;
    row-gap: 4px;
    column-gap: 8px;
  }

  /* The search box takes the cluster's first line on its own; everything else
     falls to the second. Declared rather than left to chance, so the split
     cannot re-order itself when the balance or the name length changes. */
  .site-header__controls > .nav-search,
  .site-header__controls > form.nav-search {
    flex: 0 0 100%;
    display: flex;
    justify-content: flex-end;
  }
}

/* Search on the SECOND row of the cluster, not the first (owner 2026-09-13:
   "search question 2nd row"). Same full-width break, flipped with order — so
   the account and Sign out sit on row 1 beside the menu's first line, and the
   search box sits on row 2. The header stays two rows either way; this is
   about which of the two the search belongs on. */
@media (min-width: 1240px) {
  .site-header__controls > * { order: 1; }
  .site-header__controls > .nav-search,
  .site-header__controls > form.nav-search { order: 2; }
}

/* THE BUG IN MY OWN PREVIOUS BLOCK: the nav was given `flex: 1 1 auto`, and
   flex-grow:1 makes it swallow every pixel of free space on the row — so the
   account cluster had nowhere to sit and wrapped to a third line. Measured
   signed-in at 1900: menu at tops 8 and 49, controls stranded at 86-132.

   flex-grow must be 0. The nav then takes exactly its content width, and
   margin-left:auto on the cluster still pins it hard right. Brand + menu +
   cluster measured 220 + 643 + ~350 = ~1213px against 1885px available, so
   all three share row 1 and each renders its own second line inside it:

     row 1   brand | menu line 1 | account · Sign out · theme
     row 2           menu line 2 | search

   The cluster is also given a width cap, so it wraps INTERNALLY into its two
   rows instead of stretching and pushing the menu around. */
@media (min-width: 1240px) {
  .site-header__inner > .nav { flex: 0 1 auto; }

  .site-header__controls {
    flex: 0 0 auto;
    max-width: 380px;
  }
  /* Both cluster lines hug the right edge. */
  .site-header__controls > .nav-search,
  .site-header__controls > form.nav-search { justify-content: flex-end; }
}

/* The 380px cap was wrong: with the search forced to its own full-width line
   inside the cluster, 380px left too little for the badge + Sign out + theme,
   so those wrapped again and the header grew to 213px. Cap removed; the
   cluster sizes to its own content and wraps only at the search break. */
@media (min-width: 1240px) {
  .site-header__controls { max-width: none; }
}

/* MEASURED, not guessed. Inner width 1740; brand 176 + nav 1304 + cluster 687
   = 2167, so something had to wrap — and it was the cluster, landing on a
   third line. The nav was 1304 because flex-basis:auto resolves to MAX-CONTENT,
   i.e. the width all ten items would need on one line; li.nav__break forces the
   split only once the box is narrower than that, so it never got the chance.

   flex: 1 1 0 makes the nav size from what is LEFT rather than from what it
   wants: 1740 - 176 - 687 = 877px, which comfortably holds menu line 1 (643px)
   and menu line 2 with Institute (~700px). Self-adjusting, so a longer label or
   a wider balance moves the number without needing a new hard-coded width. */
@media (min-width: 1240px) {
  .site-header__inner > .nav { flex: 1 1 0; min-width: 0; }
}

/* The cluster's first line sat ragged — Sign out at 8, theme at 10, the
   account badge at 19 — because the items are different heights and were
   aligning to the flex line's start. Centre them on the line. */
@media (min-width: 1240px) {
  .site-header__controls > * { align-self: center; }
  .site-header__inner { align-items: center; }
}

/* ===================================================================
   HEADER v2 — the owner's mockup, 2026-09-13.

   Row 1  brand | divider | Home · Question Bank · AI Test Generator ·
                  AI Notes Maker · AI Answer Checking · Learn | account · avatar
   Row 2  Structure Editor · Periodic Table · Calculator · Whiteboard ·
                  Institute   (white chips) | search (Ctrl+K) | Upgrade

   Row 2 sits on a faint tinted band, as in the mockup, so the two rows read as
   "where to go" and "what to reach for" rather than one long wrapped list.
   =================================================================== */
@media (min-width: 1240px) {
  /* The floating card. */
  #abNav { padding: 10px 16px 0; background: transparent; }
  .site-header {
    background: var(--card, #fff);
    border: 1px solid rgba(27, 42, 94, .07);
    border-radius: 18px;
    box-shadow: 0 6px 24px rgba(27, 42, 94, .07);
    overflow: hidden;          /* so the row-2 band follows the rounded corner */
  }
  .site-header__inner { padding: 0 18px; max-width: 1740px; }

  /* --- row 1 --------------------------------------------------------- */
  .site-header__inner > .site-brand {
    padding-right: 18px;
    border-right: 1px solid rgba(27, 42, 94, .10);
    margin-right: 4px;
  }

  .nav__list > .nav__item > .nav__link {
    font-size: 14.5px;
    font-weight: 600;
    padding: 9px 13px;
    border-radius: 12px;
    border: 0;
  }
  .nav__list > .nav__item > .nav__link:hover { background: rgba(27, 42, 94, .05); }

  /* The active item is a soft blue pill, as in the mockup. */
  .nav__list > .nav__item.is-current > .nav__link {
    background: #EAF1FF;
    color: #1B2A5E;
  }

  /* --- row 2: the tools become white chips on a tinted band ----------- */
  .nav__list > li.nav__break {
    margin: 8px 0 0;
    border-top: 1px solid rgba(27, 42, 94, .07);
  }
  .nav__list > li.nav__break ~ .nav__item > .nav__link {
    background: var(--card, #fff);
    border: 1px solid rgba(27, 42, 94, .09);
    border-radius: 14px;
    padding: 9px 15px;
    margin-top: 8px;
    box-shadow: 0 1px 2px rgba(27, 42, 94, .04);
  }
  .nav__list > li.nav__break ~ .nav__item > .nav__link:hover {
    border-color: rgba(27, 42, 94, .22);
    box-shadow: 0 3px 10px rgba(27, 42, 94, .08);
  }

  /* Bigger, rounder icons — the mockup's most obvious change. */
  .nav__link .nav__icon { width: 20px; height: 20px; border-radius: 7px; }

  /* --- the right-hand cluster ---------------------------------------- */
  /* The account reads as two lines, name over role/balance, as drawn. */
  #acctBadge {
    display: inline-flex; flex-direction: column; align-items: flex-end;
    line-height: 1.2; text-align: right; white-space: normal;
  }

  .nav-avatar {
    display: inline-flex; align-items: center; justify-content: center;
    width: 40px; height: 40px; border-radius: 50%;
    background: #1B2A5E; color: #fff;
    font-weight: 700; font-size: 14px; letter-spacing: .02em;
    margin-left: 10px; flex: 0 0 auto;
  }

  /* Search: rounded, roomy, with the shortcut hint inside it. */
  .nav-search { position: relative; }
  .nav-search input, .nav-search__input {
    border-radius: 999px; padding: 9px 84px 9px 38px; min-width: 260px;
  }
  .nav-search__kbd {
    position: absolute; right: 38px; top: 50%; transform: translateY(-50%);
    font: 600 10.5px/1 ui-monospace, SFMono-Regular, Menlo, monospace;
    color: #6F6F6F; background: rgba(27, 42, 94, .06);
    border-radius: 6px; padding: 4px 6px; pointer-events: none;
  }

  /* Upgrade — the one gold thing in the header, so it stays the one call. */
  .nav-upgrade {
    display: inline-flex; align-items: center; gap: 7px;
    border: 0; cursor: pointer;
    padding: 10px 20px; border-radius: 999px;
    font-weight: 700; font-size: 14px; color: #4A3A0B;
    background: linear-gradient(135deg, #F6D66B, #E9B93B);
    box-shadow: 0 3px 12px rgba(233, 185, 59, .38);
  }
  .nav-upgrade:hover { filter: brightness(1.04); }
  .nav-upgrade__crown { font-size: 14px; line-height: 1; }
}

/* Below the desktop breakpoint the drawer owns the menu, so none of the above
   applies — the chips, the card and the Upgrade pill would all fight it. */
@media (max-width: 1239px) {
  .nav-search__kbd { display: none; }   /* no physical keyboard to press it on */
  .nav-upgrade { display: none; }       /* the drawer carries the account links */
}

/* Upgrade belongs on the cluster's SECOND line, beside the search — which is
   exactly where the mockup draws it, and it also fixes a fit problem the two
   additions caused: Home on row 1 plus a ~130px Upgrade pill in the cluster's
   first line left the nav too little width, so "AI Answer Checking" and
   "Learn" spilled to a third sub-row (measured: header 141px).

   With Upgrade moved down, cluster line 1 is just account + Sign out + theme,
   and the nav gets its width back:
     line 1   account · Sign out · theme
     line 2   search (Ctrl+K) · Upgrade   */
@media (min-width: 1240px) {
  .site-header__controls > #abUpgrade { order: 2; }
  /* The search no longer takes the whole line — it shares it with Upgrade. */
  .site-header__controls > .nav-search,
  .site-header__controls > form.nav-search { flex: 1 1 auto; }
  .site-header__controls { row-gap: 8px; }
}

/* MEASURED AGAIN, because the last change traded one fault for another.
   inner 1740 = brand 195 + cluster 751 + nav 718. All three share the row, but
   the nav needs 861px for its first line (Home 91 + Question Bank 163 + AI Test
   Generator 166 + AI Notes Maker 153 + AI Answer Checking 183 + Learn 105), so
   two items spilled to a third band.

   The cluster was 751 because setting the search to flex:1 1 auto removed the
   full-width break, so badge + Sign out + search + Upgrade + theme all sat on
   ONE line. Giving the cluster a fixed 460px makes it wrap into the two lines
   the mockup draws — 305px of account on line 1, 414px of search + Upgrade on
   line 2 — and hands the nav 1740 - 195 - 460 = 1085px, comfortably past 861. */
@media (min-width: 1240px) {
  /* basis auto, not 460px: nav.js measures row 1 (the account line) and
     sets an inline width so the search stops under the start of the name. A
     flex-basis would win over that inline width and the measurement would do
     nothing. 460px stays as the cap for an unusually long name. */
  .site-header__controls { flex: 0 0 auto; width: 460px; max-width: 460px; }
  .nav-search input, .nav-search__input { min-width: 0; }
  .site-header__controls > .nav-search,
  .site-header__controls > form.nav-search { flex: 1 1 auto; min-width: 0; }
}

/* ===================================================================
   THE BRAND IS BIGGER, so the site's NAME reads as the site's name
   (owner 2026-09-13: "iska size bada karo taki branding samajh aa sake").

   It had been shrunk twice while fighting the header into two rows — the
   name down to 14.5px, smaller than the 14px menu links beside it, which
   is why it read as another menu item rather than as the masthead. The
   room exists: the measured gap between brand and controls is ~720px at
   1440 and ~1180px at 1900, against a menu row of 643px.

   Last block in the file, so it beats the earlier 14.5px rule at the same
   specificity by source order — do not move it up.
   =================================================================== */
.site-brand { gap: 12px; }
.site-brand__mark {
  width: 46px;
  height: 46px;
  border-radius: 12px;
  font-size: 20px;
}
.site-brand__name { font-size: 19px; letter-spacing: -.01em; }
.site-brand__tagline { font-size: 11px; }

@media (min-width: 1240px) {
  .site-brand__name { font-size: 19px; }
}

/* Phones keep a smaller mark — the drawer button and the badge share that
   row, and 46px there is what starts a third line. */
@media (max-width: 760px) {
  .site-brand__mark { width: 38px; height: 38px; font-size: 16px; }
  .site-brand__name { font-size: 16.5px; }
}

/* ===================================================================
   TWO MENU ROWS AT 1440 TOO, NOT FOUR (owner's standing rule from
   2026-09-13: "sare ko do row mein hi fix karo, 3 nahi")

   MEASURED at 1440 signed in, with Institute showing and Symmetry newly
   added: row 1 needs 861px and row 2 needs 817px, but the nav is handed
   only 774px — so "Learn" fell off row 1 and "Institute" off row 2, and
   the header went to four rows / 190px.

   The width is bought back from PADDING AND GAPS, not from the brand:
   the brand was just enlarged on purpose, and shrinking it here would
   undo that request to satisfy this one.

   Scoped to 1240–1640px. Above that the space already exists and the
   header is two rows at its full sizes; below 1240 the drawer takes over.
   =================================================================== */
@media (min-width: 1240px) and (max-width: 1640px) {
  /* THIRD measurement: row 2 came to 782 against a nav of 781 — over by ONE
     pixel. The last few px come from the header shell, not from the pills:
     they are already at 5px inline and squeezing them further would make the
     menu feel cramped to buy something the shell can give for free. */
  .site-header__inner { gap: 10px; padding-inline: 10px; }

  /* 6px per item per side: about 60px off row 1 and 60px off row 2. */
  /* MEASURED AGAIN after the first pass: row 1 fitted (734 of 782) but row 2
     came to 779 plus its gaps = 784, missing by TWO pixels, so Institute still
     fell to a third row. 5px inline and a zero gap buy the ~12px of headroom
     that makes it fit with room to spare rather than by a hair. */
  .nav__list > .nav__item > .nav__link { padding-inline: 5px; font-size: 13px; }
  .site-header__inner > .nav .nav__list { gap: 0; }

  /* The caret is decoration next to the label it belongs to. */
  .nav__list > .nav__item > .nav__link > svg,
  .nav__list > .nav__item > .nav__link .nav__caret { margin-left: 1px; }
}

/* MEASURED on a signed-OUT page (the tools pages): the account badge is only
   "Sign in", so the whole cluster fits on ONE row — nav.js then correctly
   measures that row as 460px wide and pins the cluster there, leaving the menu
   just 649px and wrapping it to four rows again.

   The cluster only NEEDS 460 when a full name, role and balance are on it, and
   in that case nav.js measures and sets the width itself. So in the cramped
   band the CSS starting point drops to 380 and the menu gets the difference.
   Signed in, the measurement still wins — it is an inline width. */
@media (min-width: 1240px) and (max-width: 1640px) {
  .site-header__controls { width: 380px; max-width: 380px; }
}

/* ===================================================================
   THE DROPDOWN WAS BEING CUT OFF AND PAINTED OVER (owner 2026-09-13:
   "menu pichhe chhup raha hai")

   MEASURED, two separate causes:

   1. `.site-header` carried `overflow: hidden`, so any mega panel taller
      than the header was CLIPPED at the header's own bottom edge — which
      is most of it. The clip was added "so the row-2 band follows the
      rounded corner", but row 2 is no longer a filled band: it is a
      border-top on li.nav__break plus chips that carry their own radius.
      Nothing left needs clipping, so the clip only hid the menu.

   2. The panel sits at z-index 60 inside .nav__item (position:relative,
      z-index auto). Row-2 items are also relative/auto and come LATER in
      the DOM, so in the same stacking context they paint on top of it —
      which is why Structure editor and Institute showed through the open
      panel. Lifting the OPEN item (not the panel) is what fixes it: the
      item is the stacking context the panel lives in.
   =================================================================== */
@media (min-width: 1240px) {
  .site-header { overflow: visible; }

  /* The open item outranks its later siblings. hover/focus-within are
     included because the panel opens on those too, not only on click. */
  .nav__list > .nav__item--has-sub.is-open,
  .nav__list > .nav__item--has-sub:hover,
  .nav__list > .nav__item--has-sub:focus-within { z-index: 70; }
}

/* --- any-amount wallet top-up inside the buy-credits modal (2026-09-13) --- */
.pw-custom{margin-top:14px;padding:12px 14px;border-radius:14px;background:#f7f9fc;border:1px dashed rgba(27,42,94,.18)}
.pw-custom__l{display:block;font:700 .74rem/1 Roboto,sans-serif;letter-spacing:.06em;text-transform:uppercase;color:#4a5163;margin-bottom:8px}
.pw-custom__row{display:flex;gap:8px;align-items:stretch}
.pw-custom__cur{display:grid;place-items:center;padding:0 12px;border-radius:10px;background:#1B2A5E;color:#F5D98A;font-weight:700}
.pw-custom__in{flex:1 1 auto;min-width:0;padding:10px 12px;border:1px solid #d8dce6;border-radius:10px;font:inherit;font-size:1rem}
.pw-custom__go{padding:10px 16px;border-radius:999px;border:1px solid #1B2A5E;background:#1B2A5E;color:#fff;font:600 .9rem/1 Roboto,sans-serif;cursor:pointer;white-space:nowrap}
.pw-custom__go:hover{background:#24346f}
.pw-custom__note{margin:8px 0 0;font-size:.78rem;color:#6b7488}
@media (max-width:480px){.pw-custom__row{flex-wrap:wrap}.pw-custom__go{flex:1 1 100%}}
.ev5-help-ticket{background:#fff;color:#1B2A5E;border:1px solid #1B2A5E}
