﻿/* =========================================================
   VidhyaBhavan — main stylesheet
   Theme: white background, blue primary
   ========================================================= */

:root {
  --primary: #1a2ef0;
  --primary-dark: #0f1ea8;
  --primary-light: #eaecfe;
  --accent: #ff7a1a;
  --accent-deep: #c4560a; /* AA-contrast orange for text on light backgrounds */
  --accent-soft: #ffb703;
  --dark: #14192b;
  --text: #1f2430;
  --muted: #5b6472;
  --border: #e6e9f0;
  --bg: #ffffff;
  --bg-soft: #f6f8fd;
  /* Skeleton fill. Deliberately NOT --bg-soft: profile and scores set that as
     their own page background, so a skeleton in --bg-soft was invisible — the
     blocks and the page behind them were both rgb(246,248,253). */
  --skeleton: #e1e6f0;
  --tint-peach: #fdf1e3;
  --tint-blue: #eaecfe;
  --tint-mint: #e5f7ee;
  --tint-lav: #efecfd;
  --radius: 16px;
  --shadow: 0 6px 24px rgba(20, 25, 43, 0.08);
  --shadow-lg: 0 12px 40px rgba(20, 25, 43, 0.14);
  --header-h: 64px;

  /* ---------------------------------------------------------------------
     THE 14 AUG 2026 HOME REDESIGN — see §34

     The owner's design canvas used a more saturated blue (#1a2ef0) than the
     site's old --primary (#1a56db). It was deliberately NOT wired into
     --primary at the time: that token paints ~52 marketing pages, and
     repainting every one of them was a far bigger visual change than a
     home-page redesign was asked to make.

     16 Aug 2026: the whole site moved onto this blue — --primary below is
     now #1a2ef0 too. --vh-blue and its dark/tint variants stay defined
     separately because the shared chrome and home-page rules already
     reference them directly; the two values matching didn't require
     rewiring those rules onto --primary as well.
     --------------------------------------------------------------------- */
  --vh-blue: #1a2ef0;
  --vh-blue-dark: #0f1ea8;
  --vh-blue-tint: #eaecfe;
  /* ---------------------------------------------------------------------
     TWO on-dark blues, because text and a filled button want OPPOSITE things.

     The canvas used #1a2ef0 for headings on near-black and for the Buy Now
     fill. Measured in the browser, both were broken and the owner spotted it:

       heading  #1a2ef0 on #0b0b0d ......... 2.52:1  (fails the 3:1 large floor)
       fill     #1a2ef0 vs the #15161a card  2.32:1  (button barely separates)

     Lightening one token cannot fix both: the lighter it gets, the better it
     reads as TEXT and the worse WHITE reads on it as a FILL. So:

       --vh-blue-on-dark   #7c88ff   text on near-black ........... 6.39:1
       --vh-blue-fill-dark #4f5dff   fill vs the card ............. 3.74:1
                                     white text on that fill ...... 4.84:1

     Both stay in the #1a2ef0 hue family (~235deg), so they read as the brand
     rather than as a second colour. Do not collapse them back into one.
     --------------------------------------------------------------------- */
  --vh-blue-on-dark: #7c88ff;
  --vh-blue-fill-dark: #4f5dff;
  --vh-ink: #15161a;
  --vh-band: #eef2fd;
  --vh-yellow: #ffe600;
  --vh-line: #e3e6ef;
  /* the design's 1440px canvas minus its own 44px gutters */
  --vh-max: 1352px;
  /* Barlow Condensed is the design's display face. Poppins stays the BODY face
     everywhere except the home page, because Poppins is what carries the
     Devanagari subset the library's 14,105 Marathi questions render through
     (see the @font-face note below). Noto stays last in every stack. */
  --vh-cond: "Barlow Condensed", "Poppins", "Segoe UI", system-ui, sans-serif;
}

/* The site header is 72px tall on desktop (trimmed down from 96px, owner,
   16 Aug 2026), and --header-h is what `scroll-padding-top`, the mobile nav
   and the library's sticky chapter rail all measure against. Scoping it to
   pages that ACTUALLY have the header — rather than redeclaring it in :root —
   is what keeps admin.html (58px), employee.html, register.html and test.html
   on the value each of them was tuned to. A page added later gets the right
   number for free, and a page without a header can never inherit an offset
   for a header it does not have.

   ⚠ It must be declared on `html`, NOT on `body`. `scroll-padding-top` is set
   on `html` (see below), and html does not inherit from its own child — put
   this on body and every in-page anchor jump silently compensates for the
   wrong header height, leaving the target tucked under it. */
html:has(.site-header) { --header-h: 72px; }

* { margin: 0; padding: 0; box-sizing: border-box; }

html { scroll-behavior: smooth; scroll-padding-top: calc(var(--header-h) + 12px); }

html, body {
  /* clip horizontal overflow WITHOUT creating a scroll container
     (overflow-x: hidden makes body scrollable via scrollIntoView/focus) */
  overflow-x: hidden;
  overflow-x: clip;
}

/* ---------------------------------------------------------------------------
   MARATHI — Noto Sans Devanagari, SELF-HOSTED, AS A SAFETY NET

   READ THIS BEFORE "FIXING" THE ORDER BELOW.

   POPPINS ALREADY CONTAINS DEVANAGARI. It is an Indian Type Foundry face and
   its Google Fonts build ships a U+0900-097F subset. Measured in the browser:
   a Marathi string is 427.05px in Poppins and 427.05px in the body stack, so
   Poppins is genuinely doing the rendering. The library's 14,105 Marathi
   questions were NEVER falling back to a system font, and there was never a
   tofu-box risk. An earlier note in PROJECT-CONTEXT claimed the opposite; it
   was wrong.

   So what is this file for? Poppins' Devanagari comes from fonts.gstatic.com.
   If Google Fonts is slow, blocked or unreachable — which happens on some
   Indian networks and school/office filters — Poppins does not load AT ALL and
   Marathi drops to whatever the device has. THIS is the case Noto covers: it is
   served from our own origin, so Devanagari always has a real font behind it.

   Poppins therefore stays FIRST and normally wins; Noto only ever renders when
   Poppins failed to arrive. Do not reorder these to "make Noto work" — Noto not
   being used is the correct steady state.

   Only the Devanagari subset is shipped (118 KB), and `unicode-range` means the
   browser fetches it ONLY when a Devanagari character is on the page, so an
   English-only page pays nothing. It is a variable font: one file serves 400-700.
--------------------------------------------------------------------------- */
@font-face {
  font-family: "Noto Sans Devanagari";
  font-style: normal;
  font-weight: 400 700;
  font-stretch: 100%;
  font-display: swap;
  src: url("../vendor/noto-devanagari/noto-sans-devanagari-v30.woff2") format("woff2");
  unicode-range: U+0900-097F, U+1CD0-1CF9, U+200C-200D, U+20A8, U+20B9, U+20F0,
                 U+25CC, U+A830-A839, U+A8E0-A8FF, U+11B00-11B09;
}

body {
  /* Poppins first, Noto second: a browser picks per CHARACTER, and Poppins has
     no Devanagari glyphs, so Latin stays Poppins and Devanagari falls through
     to Noto automatically. No per-element language class is needed anywhere. */
  font-family: "Poppins", "Noto Sans Devanagari", "Segoe UI", system-ui, -apple-system, sans-serif;
  color: var(--text);
  background: var(--bg);
  line-height: 1.6;
}

img, svg { display: block; max-width: 100%; }
/* the `hidden` attribute must always win — author display rules (e.g. on an
   avatar or a flex row) otherwise override the UA stylesheet and leak content */
[hidden] { display: none !important; }
a { color: inherit; text-decoration: none; }
ul { list-style: none; }
button { font-family: inherit; cursor: pointer; }

.container {
  width: min(1120px, 92%);
  margin-inline: auto;
}

/* ---------- Buttons ---------- */
.btn {
  display: inline-block;
  padding: 12px 28px;
  border-radius: 10px;
  font-weight: 600;
  font-size: 0.95rem;
  border: none;
  transition: transform 0.2s ease, box-shadow 0.2s ease, background 0.2s ease;
}
.btn:hover { transform: translateY(-2px); box-shadow: var(--shadow); }
.btn-primary { background: var(--primary); color: #fff; }
.btn-primary:hover { background: var(--primary-dark); }
.btn-dark { background: var(--dark); color: #fff; padding: 9px 20px; }
/* Header account actions are navigation, not destructive or secondary actions.
   Keep their emphasis aligned with the brand's primary blue. */
.header-actions .btn-dark { background: var(--primary); }
.header-actions .btn-dark:hover { background: var(--primary-dark); }
.btn-light { background: #fff; color: var(--primary); }
.btn-accent { background: var(--accent); color: #fff; }
.btn-accent:hover { background: var(--accent-deep); }
.btn-block { width: 100%; }

/* =========================================================
   PROMO STRIP  (§34)
   The tricolour bar above the header. It is a SIBLING of .site-header, not a
   child, so it scrolls away and the sticky bar stays 72px rather than 110px.
   Everything that used to anchor to `top: var(--header-h)` — the mobile nav
   and the mega menus — is positioned against the header itself instead (see
   below), so the strip's presence can never push a panel out of alignment.
   ========================================================= */
.vh-promo {
  height: 38px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding-inline: 16px;
  background: linear-gradient(90deg, #ff9933 0%, #ff9933 26%, #ffffff 42%,
                              #ffffff 58%, #138808 74%, #138808 100%);
}
/* The canvas drew an Ashoka chakra to the left of this line. Removed at the
   owner's request (14 Aug 2026) — text only. */
.vh-promo-in {
  font-family: var(--vh-cond);
  font-weight: 700;
  font-size: 1rem;
  letter-spacing: 0.02em;
  color: #111;
  text-align: center;
}

/* =========================================================
   HEADER
   ========================================================= */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--bg);
  border-bottom: 1px solid var(--border);
  transition: box-shadow 0.25s ease;
}
.site-header.scrolled { box-shadow: 0 4px 20px rgba(20, 25, 43, 0.1); }

.header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  height: var(--header-h);
}
.site-header .header-inner {
  width: 100%;
  max-width: none;
  margin: 0;
  /* Left is near-zero on purpose — the logo sits at the extreme left edge
     (owner, 16 Aug 2026). Right keeps the old gutter so the nav pill and
     account button don't press against the edge too. */
  padding-left: 6px;
  padding-right: clamp(16px, 3vw, 44px);
  box-sizing: border-box;
}

.brand { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }
/* The owner's logo file landed 16 Aug 2026 (public/images/logo.webp) and now
   ships in the header — §8's "the wordmark IS the logo" no longer applies
   there. There is deliberately NO onerror fallback on the <img>: employee.html
   has carried a silently-hidden broken image reference for months because of
   exactly that pattern (§24), so the logo is either present in the markup or
   it is not there at all.
   .brand-name is unused in the header now but stays live in the footer's
   `.brand.light` (dark-background) variant, which was not asked to change. */
.brand-logo { height: 40px; width: auto; }
.brand-name { font-size: 1.45rem; font-weight: 700; color: var(--dark); letter-spacing: -0.02em; }
.brand-name span { color: var(--vh-blue); }
.brand.light .brand-name { color: #fff; }
.brand.light .brand-name span { color: #8db3ff; }

/* The nav pill and the account button are ONE right-hand group in the design
   canvas, with only the wordmark on the left — the nav is not centred. Without
   this wrapper, .header-inner's `space-between` spreads three children and
   parks the nav in the middle of the header. */
.header-right { display: flex; align-items: center; gap: 14px; }

/* The nav is a raised pill card in the new design, not a bare row of links. */
.main-nav {
  display: flex;
  align-items: center;
  gap: 6px;
  background: #fff;
  border: 1px solid var(--vh-line);
  border-radius: 12px;
  padding: 8px 10px;
  box-shadow: 0 6px 18px rgba(20, 40, 90, 0.07);
}
.main-nav a {
  padding: 8px 14px;
  border-radius: 8px;
  font-family: var(--vh-cond);
  font-weight: 600;
  font-size: 1rem;
  color: #20232b;
  white-space: nowrap;
  transition: color 0.2s ease, background 0.2s ease;
}
.main-nav a:hover { color: var(--vh-blue); background: var(--vh-blue-tint); }
.main-nav a[aria-current="page"] {
  padding-inline: 16px;
  background: var(--vh-blue-tint);
  color: var(--vh-blue);
  font-weight: 700;
}
.main-nav .nav-login { display: none; } /* shown only in the mobile dropdown */

.header-actions { display: flex; align-items: center; gap: 14px; }
.header-actions .btn-dark {
  background: var(--vh-blue);
  border-radius: 10px;
  padding: 11px 20px;
  font-family: var(--vh-cond);
  font-weight: 700;
  font-size: 1.06rem;
  box-shadow: 0 8px 20px rgba(26, 46, 240, 0.25);
}
.header-actions .btn-dark:hover { background: var(--vh-blue-dark); }
/* The staff Console link is injected into .header-actions by vb-firebase.js,
   so it sits next to the account button and has to match its blue. */
.header-actions .btn-console { background: var(--vh-blue); }
.header-actions .btn-console:hover { background: var(--vh-blue-dark); }

.nav-toggle {
  display: none;
  flex-direction: column;
  gap: 5px;
  background: none;
  border: none;
  padding: 8px;
}
.nav-toggle span {
  width: 24px;
  height: 2.5px;
  background: var(--dark);
  border-radius: 2px;
  transition: transform 0.25s ease, opacity 0.25s ease;
}
.nav-toggle.open span:nth-child(1) { transform: translateY(7.5px) rotate(45deg); }
.nav-toggle.open span:nth-child(2) { opacity: 0; }
.nav-toggle.open span:nth-child(3) { transform: translateY(-7.5px) rotate(-45deg); }

/* =========================================================
   HERO CAROUSEL
   ========================================================= */
.hero { position: relative; }

.carousel {
  position: relative;
  overflow: hidden;
  width: 100%;
  max-width: 100%;
  margin: 0;
  padding: 0;
  background: var(--bg-soft);
}

.carousel-track {
  display: flex;
  transition: transform 0.6s cubic-bezier(0.4, 0, 0.2, 1);
}

.slide { min-width: 100%; }

.slide-link { display: block; }

/* single poster (no carousel) — shown at its natural ratio, never cropped */
.hero-banner {
  display: block;
  width: min(900px, 88%);
  margin: 16px auto 0;
  border-radius: 16px;
  overflow: hidden;
  box-shadow: var(--shadow);
  background: var(--bg-soft);
}
.hero-banner img { width: 100%; height: auto; display: block; }

.slide img {
  width: 100%;
  height: auto;
  aspect-ratio: auto;
  object-fit: contain;
  display: block;
}

/* A single slide means the arrows AND the dots would be controls that cannot
   do anything — clicking either just re-shows the same banner (§14). The
   arrows already had this guard; the dots did not, because until now the hero
   always carried at least two slides. script.js still builds one dot per
   slide unconditionally — CSS hides it rather than adding a branch there, so
   adding a second slide later makes the dots reappear for free. */
#heroCarousel:has(.slide:only-child) .carousel-arrow,
#heroCarousel:has(.slide:only-child) .carousel-dots { display: none; }

.carousel-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: none;
  background: rgba(255, 255, 255, 0.92);
  color: var(--dark);
  font-size: 1rem;
  box-shadow: var(--shadow);
  z-index: 5;
  opacity: 0;
  transition: opacity 0.25s ease, background 0.2s ease;
}
.carousel:hover .carousel-arrow, .carousel-arrow:focus-visible { opacity: 1; }
.carousel-arrow:hover { background: #fff; }
.carousel-arrow.prev { left: 14px; }
.carousel-arrow.next { right: 14px; }

.carousel-dots {
  position: absolute;
  bottom: 12px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 2px;
  z-index: 7;
  background: rgba(20, 25, 43, 0.4); /* readable over any poster */
  padding: 1px 5px;
  border-radius: 999px;
  backdrop-filter: blur(4px);
}
.carousel-dots button {
  width: 18px;
  height: 18px;
  border: none;
  background: transparent;
  padding: 0;
  display: grid;
  place-items: center;
  border-radius: 999px;
}
.carousel-dots button::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.65);
  transition: width 0.25s ease, background 0.25s ease;
}
.carousel-dots button.active::before { width: 18px; background: #fff; }

/* =========================================================
   EXPLORE CATEGORIES
   ========================================================= */
.categories { padding-block: 44px 20px; }
.categories .section-title { font-size: clamp(1.45rem, 2.4vw, 1.8rem); line-height: 1.2; }
.categories .section-sub { max-width: none; margin: 3px auto 24px; font-size: .76rem; line-height: 1.45; }
.cat-grid { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 12px; }
.cat-card {
  --cat: var(--primary);
  --cat-border: #dce8fd;
  --cat-soft: #f6f9ff;
  display: flex;
  flex-direction: column;
  align-items: center;
  min-height: 174px;
  padding: 14px 10px 12px;
  text-align: center;
  background: #fff;
  border: 1px solid var(--cat-border);
  border-radius: 8px;
  transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease;
}
.cat-card--jee { --cat: #255bd5; --cat-border: #d5e3ff; --cat-soft: #f5f8ff; }
.cat-card--neet { --cat: #319766; --cat-border: #d5eee1; --cat-soft: #f3fbf7; }
.cat-card--foundation { --cat: #8758c7; --cat-border: #e9dcfb; --cat-soft: #faf6ff; }
.cat-card--govt { --cat: #ef7627; --cat-border: #fde3d1; --cat-soft: #fff8f3; }
.cat-card--mhtcet { --cat: #197f8e; --cat-border: #d6e9ed; --cat-soft: #f4fbfc; }
.cat-card:hover { transform: translateY(-3px); border-color: var(--cat); box-shadow: 0 10px 22px rgba(20, 25, 43, .08); }
.cat-icon { display: grid; place-items: center; width: 60px; height: 60px; margin-bottom: 2px; color: var(--cat); }
.cat-icon svg { width: 100%; height: 100%; }
.cat-icon--image { position: relative; display: block; width: 92px; height: 86px; margin-bottom: 0; overflow: hidden; isolation: isolate; }
.cat-icon--image::before { content: ""; position: absolute; inset: 10px; z-index: 0; border-radius: 50%; background: var(--cat-soft); filter: blur(5px); }
.cat-icon--image img { position: absolute; z-index: 1; top: 50%; left: 50%; width: 140px; height: 140px; max-width: none; object-fit: contain; transform: translate(-50%, -50%); mix-blend-mode: multiply; -webkit-mask-image: radial-gradient(ellipse 48% 50% at center, #000 50%, rgba(0, 0, 0, .86) 65%, transparent 86%); mask-image: radial-gradient(ellipse 48% 50% at center, #000 50%, rgba(0, 0, 0, .86) 65%, transparent 86%); }
.cat-icon--jee-image img { width: 148px; height: 148px; }
.cat-icon--neet-image img { width: 142px; height: 142px; }
.cat-icon--foundation-image img { width: 148px; height: 148px; }
.cat-icon--govt-image img { width: 140px; height: 140px; }
.cat-icon--mhtcet-image img { width: 142px; height: 142px; mix-blend-mode: normal; }
.cat-card h3 { color: var(--cat); font-size: .92rem; font-weight: 700; line-height: 1.25; margin: 1px 0 8px; }
.cat-chips { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px; margin-top: auto; }
.cat-chips a { padding: 3px 8px; border: 1px solid var(--cat-border); border-radius: 5px; color: var(--cat); background: var(--cat-soft); font-size: .62rem; font-weight: 600; line-height: 1.2; white-space: nowrap; transition: color .2s ease, background .2s ease, border-color .2s ease; }
.cat-chips a:hover { color: #fff; border-color: var(--cat); background: var(--cat); }

@media (max-width: 992px) { .cat-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 700px) { .cat-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .cat-grid { grid-template-columns: 1fr; } }

/* =========================================================
   FEATURE STRIP
   ========================================================= */
.features { margin-top: 20px; position: relative; }

.feature-card {
  background: #fff;
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  padding: 20px 8px;
}
.feature {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 2px;
  padding: 5px 10px;
  border-right: 1px solid var(--border);
}
.feature:last-child { border-right: none; }
.feature strong { font-size: 0.98rem; margin-top: 6px; }
.feature span:last-child { color: var(--muted); font-size: 0.82rem; }

.f-icon {
  width: 46px;
  height: 46px;
  border-radius: 12px;
  display: grid;
  place-items: center;
  padding: 10px;
}
.f-red { background: #fdeaea; color: #e0344a; }
.f-blue { background: var(--tint-blue); color: var(--primary); }
.f-purple { background: var(--tint-lav); color: #7c5cd8; }
.f-orange { background: var(--tint-peach); color: var(--accent); }

/* =========================================================
   SECTIONS (shared)
   ========================================================= */
.section { padding: 56px 0; }

.section-title {
  text-align: center;
  font-size: clamp(1.45rem, 3.2vw, 2rem);
  font-weight: 800;
  letter-spacing: -0.02em;
}
.section-title span { color: var(--primary); }
.section-title.left { text-align: left; }

.section-sub {
  text-align: center;
  color: var(--muted);
  max-width: 640px;
  margin: 8px auto 34px;
}

.cards-grid { display: grid; gap: 24px; }

/* tints */
.tint-peach { background: var(--tint-peach); }
.tint-blue { background: var(--tint-blue); }
.tint-mint { background: var(--tint-mint); }
.tint-lav { background: var(--tint-lav); }

/* avatars */
.avatar {
  width: 72px;
  height: 72px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-weight: 700;
  font-size: 1.3rem;
  color: #fff;
  margin-inline: auto;
  box-shadow: 0 4px 14px rgba(20, 25, 43, 0.18);
}
.avatar-lg { width: 96px; height: 96px; font-size: 1.7rem; }
.avatar-sm { width: 44px; height: 44px; font-size: 0.95rem; margin-inline: 0; box-shadow: none; }

.av-1 { background: linear-gradient(135deg, #ff8f4d, #f4562a); }
.av-2 { background: linear-gradient(135deg, #4d8dff, #1a2ef0); }
.av-3 { background: linear-gradient(135deg, #37c978, #148f52); }
.av-4 { background: linear-gradient(135deg, #a78bfa, #6d4ed8); }
.av-5 { background: linear-gradient(135deg, #38bdf8, #0a7bb8); }
.av-6 { background: linear-gradient(135deg, #fb7185, #dc3552); }

.chip {
  display: inline-block;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 4px 14px;
  font-size: 0.8rem;
  font-weight: 500;
  color: var(--muted);
}

/* =========================================================
   STATS
   ========================================================= */
.stats-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 24px; }

.stat-tile {
  border-radius: var(--radius);
  padding: 44px 20px;
  text-align: center;
  transition: transform 0.25s ease;
}
.stat-tile:hover { transform: translateY(-6px); }
.stat-tile strong { display: block; font-size: clamp(1.7rem, 3vw, 2.4rem); font-weight: 800; color: var(--dark); }
.stat-tile span { color: var(--muted); font-size: 0.95rem; }

/* =========================================================
   REVIEWS
   ========================================================= */
.reviews { background: var(--bg-soft); }

/* Carousel: cards sit in one flex row; a page shifts by (viewport + gap),
   which works out to the same distance whatever --rv-per is. */
.reviews-carousel {
  --rv-gap: 24px;
  --rv-per: 3;
  --rv-index: 0;
  position: relative;
  padding: 0 60px; /* side gutters hold the arrows */
}

.rv-viewport { overflow: hidden; }

.rv-track {
  display: flex;
  gap: var(--rv-gap);
  align-items: stretch; /* every card matches the tallest — no ragged bottoms */
  transform: translateX(calc(var(--rv-index) * -1 * (100% + var(--rv-gap))));
  transition: transform 0.5s cubic-bezier(0.4, 0, 0.2, 1);
}

.rv-track .review-card {
  flex: 0 0 calc((100% - (var(--rv-per) - 1) * var(--rv-gap)) / var(--rv-per));
  margin: 4px 0; /* breathing room so the hover lift isn't clipped by the viewport */
}

.rv-arrow {
  position: absolute;
  top: calc(50% - 22px); /* back out half the 44px dots strip so this centres on the cards */
  transform: translateY(-50%);
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: none;
  background: var(--dark);
  color: #fff;
  font-size: 0.95rem;
  box-shadow: var(--shadow);
  z-index: 5;
  transition: background 0.2s ease, transform 0.2s ease;
}
.rv-arrow:hover { background: var(--primary); }
.rv-arrow:active { transform: translateY(-50%) scale(0.94); }
.rv-arrow.prev { left: 0; }
.rv-arrow.next { right: 0; }

/* in flow, and free to wrap — 12 dots don't fit one row on a narrow phone */
.rv-dots {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 4px;
  margin-top: 20px;
}
.rv-dots button {
  width: 24px;
  height: 24px; /* touch target; the visible dot is drawn via ::before */
  border: none;
  background: transparent;
  padding: 0;
  display: grid;
  place-items: center;
}
.rv-dots button::before {
  content: "";
  width: 9px;
  height: 9px;
  border-radius: 999px;
  background: #cfd6e4;
  transition: background 0.25s ease, transform 0.25s ease;
}
.rv-dots button:hover::before { background: #a9b4c8; }
.rv-dots button.active::before { background: var(--dark); transform: scale(1.15); }

.review-card {
  background: #fff;
  border-radius: var(--radius);
  padding: 28px;
  box-shadow: var(--shadow);
  display: flex;
  flex-direction: column;
  gap: 14px;
  transition: transform 0.25s ease, box-shadow 0.25s ease;
}
.review-card:hover { transform: translateY(-6px); box-shadow: var(--shadow-lg); }

.review-stars { color: #f5a623; font-size: 1.1rem; letter-spacing: 2px; }
/* half star: fill the left half only, via a hard-stop gradient clipped to the glyph */
.review-stars .half {
  background: linear-gradient(90deg, #f5a623 50%, #dbe0ea 50%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.review-stars .empty { color: #dbe0ea; }
.review-card > p { color: var(--text); font-size: 0.95rem; flex: 1; }

.reviewer { border-top: 1px solid var(--border); padding-top: 14px; }
.reviewer strong { display: block; font-size: 0.95rem; }
.reviewer span { color: var(--muted); font-size: 0.82rem; }

/* =========================================================
   CALLBACK
   ========================================================= */
.callback-inner {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(440px, 560px);
  gap: 46px;
  align-items: start;
}

.callback { padding-block: 40px 44px; }
.callback .section-title { font-size: clamp(1.45rem, 2.35vw, 1.8rem); }
.callback-info > p { color: var(--muted); margin: 10px 0 17px; max-width: 430px; font-size: .93rem; line-height: 1.55; }

.callback-points li {
  position: relative;
  padding-left: 27px;
  margin-bottom: 9px;
  font-weight: 500;
  font-size: .93rem;
}
.callback-points li::before {
  content: "✓";
  position: absolute;
  left: 0;
  top: 0;
  width: 19px;
  height: 19px;
  border-radius: 50%;
  background: var(--primary-light);
  color: var(--primary);
  font-size: 0.8rem;
  font-weight: 700;
  display: grid;
  place-items: center;
}

.callback-contact { margin-top: 20px; color: var(--muted); font-size: .88rem; }
.callback-contact a { color: var(--primary); font-weight: 600; }

.callback-form {
  background: #fff;
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  border: 1px solid var(--border);
  padding: 24px;
}
.callback-form h3 { font-size: 1.08rem; margin-bottom: 15px; }

.callback-form .form-row { margin-bottom: 12px; }
.form-row label {
  display: block;
  font-weight: 500;
  font-size: 0.88rem;
  margin-bottom: 5px;
}
.form-row label span { color: #e0344a; margin-left: 2px; }
.form-row label em { color: var(--muted); font-style: normal; font-weight: 400; }

.form-row input,
.form-row select,
.form-row textarea {
  width: 100%;
  padding: 9px 12px;
  border: 1.5px solid var(--border);
  border-radius: 10px;
  font-family: inherit;
  font-size: .88rem;
  color: var(--text);
  background: #fff;
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
}
.callback-form textarea { min-height: 88px; }
.callback-form .btn { padding: 11px 18px; font-size: .9rem; }
.form-row input:focus,
.form-row select:focus,
.form-row textarea:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 3px rgba(26, 46, 240, 0.15);
}
.form-row input.invalid, .form-row select.invalid { border-color: #e0344a; }

.form-error { color: #e0344a; font-size: 0.88rem; margin-bottom: 12px; }
.form-success {
  margin-top: 14px;
  background: #e5f7ee;
  color: #14804a;
  font-weight: 500;
  font-size: 0.92rem;
  padding: 12px 16px;
  border-radius: 10px;
  text-align: center;
}

/* =========================================================
   FOOTER  (redesigned §34)
   Black ground, yellow column headings, a full-bleed blue policy bar and a
   black copyright bar under it. The two bars are full-bleed by sitting OUTSIDE
   the container rather than by the design canvas's `margin: 0 -66px` trick,
   which only works at one fixed page width.
   ========================================================= */
.site-footer { background: #000; color: #e2e2e6; }
/* The footer content spans wider than the 1120px marketing container, matching
   the design's 1440px canvas minus its gutters. */
.site-footer .container { width: min(var(--vh-max), 92%); }

/* Sits high and right, close to the top edge of the black — the owner reported
   44px as sitting too low (14 Aug 2026). */
.footer-top {
  padding-top: 18px;
  text-align: right;
}
.footer-hash {
  font-family: "Caveat", "Barlow Condensed", cursive;
  font-size: 2.1rem;
  font-weight: 700;
  color: #fff;
  line-height: 1.2;
}

.footer-grid {
  display: grid;
  grid-template-columns: 1.5fr 1fr 1fr 1.1fr;
  gap: 44px;
  padding: 26px 0 44px;
}

.footer-brand p {
  margin-top: 18px;
  max-width: 330px;
  font-family: var(--vh-cond);
  font-weight: 500;
  font-size: 1rem;
  line-height: 1.5;
  color: #e2e2e6;
  text-wrap: pretty;
}

.site-footer h4 {
  font-family: var(--vh-cond);
  font-weight: 800;
  font-size: 1.375rem;
  color: var(--vh-yellow);
  margin-bottom: 12px;
}
.site-footer ul li {
  margin-bottom: 0;
  font-family: var(--vh-cond);
  font-weight: 500;
  font-size: 1.06rem;
  line-height: 1.5;
  padding: 4px 0;
}
.site-footer ul a { transition: color 0.2s ease; }
.site-footer ul a:hover { color: var(--vh-yellow); }

.footer-contact li { line-height: 1.5; }

/* full-bleed blue bar: Privacy · Terms · Refund.
   These are TEXT, not links, and that is deliberate — none of those three pages
   exists yet (§15 records the content as "owner will supply"), and the design
   canvas draws them as plain labels too. They become <a>s the day the pages do. */
.footer-policy { background: var(--vh-blue); }
.footer-policy .container {
  min-height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 12px 66px;
  padding-block: 10px;
  font-family: var(--vh-cond);
  font-weight: 600;
  font-size: 1rem;
  color: #fff;
  text-align: center;
}

.footer-bottom {
  background: #000;
  min-height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 10px 0;
  font-family: var(--vh-cond);
  font-weight: 500;
  font-size: 0.94rem;
  color: #fff;
  text-align: center;
}

/* Floating call button */
.call-float {
  position: fixed;
  right: 18px;
  bottom: 18px;
  z-index: 90;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  background: var(--primary);
  display: grid;
  place-items: center;
  padding: 14px;
  box-shadow: var(--shadow-lg);
  transition: transform 0.2s ease, background 0.2s ease;
}
.call-float:hover { transform: scale(1.08); background: var(--primary-dark); }

/* =========================================================
   PLACEHOLDER PAGES (test series / materials / etc.)
   ========================================================= */
.placeholder-hero {
  min-height: calc(100vh - var(--header-h) - 260px);
  display: grid;
  place-items: center;
  text-align: center;
  padding: 80px 0;
}
.placeholder-hero .ph-icon {
  width: 88px;
  height: 88px;
  border-radius: 24px;
  background: var(--primary-light);
  color: var(--primary);
  display: grid;
  place-items: center;
  padding: 22px;
  margin: 0 auto 26px;
}
/* when a form section follows, the hero shouldn't eat the whole first screen */
.placeholder-hero.compact { min-height: 0; padding: 64px 0 8px; }
.placeholder-hero h1 { font-size: clamp(1.8rem, 4vw, 2.6rem); font-weight: 800; letter-spacing: -0.02em; }
.placeholder-hero h1 span { color: var(--primary); }
.placeholder-hero p { color: var(--muted); max-width: 520px; margin: 12px auto 30px; }
/* no intro paragraph to space things out — give the button its own gap */
.placeholder-hero h1 + .btn { margin-top: 28px; }

/* Visually hidden (screen-reader only) */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* =========================================================
   REVEAL ON SCROLL
   ========================================================= */
.reveal {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.6s ease, transform 0.6s ease;
}
.reveal.visible { opacity: 1; transform: translateY(0); }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation: none !important; transition: none !important; }
  .reveal { opacity: 1; transform: none; }
}

/* =========================================================
   RESPONSIVE
   ========================================================= */
/* Compact header so the full nav pill fits between 993px and 1240px. The pill
   carries six items plus two carets, so it needs more room than the old bare
   row did — this range starts higher than the 1120px it used to. */
@media (max-width: 1240px) {
  .main-nav { gap: 2px; padding: 6px 8px; }
  .main-nav a { padding: 7px 10px; font-size: 0.94rem; }
  .brand-logo { height: 34px; }
  .brand-name { font-size: 1.25rem; }
  .header-actions { gap: 10px; }
  .header-actions .btn-dark { padding: 10px 15px; font-size: 0.98rem; }
}

@media (max-width: 1024px) {
  .stats-grid { grid-template-columns: repeat(2, 1fr); }
  .footer-grid { grid-template-columns: 1fr 1fr; }
  .reviews-carousel { --rv-per: 2; }
}

/* Hide hover-revealed arrows on touch devices — swipe & dots cover navigation */
@media (hover: none) {
  .carousel-arrow { display: none; }
}

@media (max-width: 992px) {
  /* absolute against the sticky header, not fixed to the viewport, so the
     panel stays glued to the header whether or not the promo strip is still
     on screen (§34) */
  .main-nav {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    background: #fff;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: 12px 4%;
    /* drop the desktop pill: it is a full-width dropdown panel down here */
    border: none;
    border-radius: 0;
    border-bottom: 1px solid var(--border);
    box-shadow: var(--shadow-lg);
    transform: translateY(-16px);
    opacity: 0;
    visibility: hidden;
    transition: transform 0.25s ease, opacity 0.25s ease, visibility 0.25s;
  }
  .main-nav.open { transform: translateY(0); opacity: 1; visibility: visible; }
  .main-nav { max-height: calc(100vh - var(--header-h)); overflow-y: auto; }
  .main-nav > a { padding: 14px 10px; border-bottom: 1px solid var(--border); border-radius: 0; font-size: 0.95rem; }
  .main-nav > a:last-child { border-bottom: none; }
  .main-nav .nav-login { display: block; color: var(--primary); font-weight: 600; }

  /* A 72px sticky bar still costs too much of a phone viewport; the nav
     pill is a dropdown panel at this width anyway, so the header only has to
     hold the logo and the account button. */
  html:has(.site-header) { --header-h: 64px; }
  .brand-logo { height: 28px; }
  .vh-promo { height: auto; min-height: 32px; padding-block: 5px; }
  .vh-promo-in { font-size: 0.86rem; line-height: 1.25; }

  .nav-toggle { display: flex; }
  .btn-dark { padding: 9px 16px; font-size: 0.85rem; }
  .header-actions .btn-dark { padding: 9px 16px; font-size: 0.95rem; }

  /* full-bleed banner on tablets & phones, like the PW app */
  .carousel { width: 100%; margin-top: 0; border-radius: 0; box-shadow: none; }
  .hero-banner { width: 100%; margin-top: 0; border-radius: 0; box-shadow: none; }
  .course-hero { width: 100%; margin-top: 0; border-radius: 0; }

  .feature-card { grid-template-columns: repeat(2, 1fr); gap: 18px 0; }
  .feature:nth-child(2) { border-right: none; }

  .callback-inner { grid-template-columns: 1fr; gap: 40px; }

}

@media (max-width: 620px) {
  /* one card per view; arrows drop out, swipe & dots take over */
  .reviews-carousel { --rv-per: 1; --rv-gap: 16px; padding: 0; }
  .rv-arrow { display: none; }
  .stats-grid { grid-template-columns: 1fr 1fr; gap: 14px; }
  .stat-tile { padding: 30px 14px; }
  .section { padding: 56px 0; }
  .footer-grid { grid-template-columns: 1fr; gap: 30px; }
  .footer-top { text-align: center; padding-top: 34px; }
  .footer-hash { font-size: 1.6rem; }
  .footer-policy .container { gap: 8px 24px; font-size: 0.94rem; }
  .carousel-arrow { display: none; }
  /* Both selectors are needed: the redesign styles the account button as
     `.header-actions .btn-dark` (0,2,0), which outranks a bare `.btn-dark`
     (0,1,0) — so hiding it on a phone silently stopped working until this line
     matched that specificity. The control is not lost: vb-firebase.js relabels
     `.btn-dark, .nav-login` together, so the mobile dropdown's own
     "Login / Register" becomes "Hi, <name>" and links to the profile. */
  .btn-dark,
  .header-actions .btn-dark { display: none; }
}

/* =========================================================
   COURSES MEGA MENU
   (kept at the end so these rules win over generic nav styles)
   ========================================================= */
.nav-drop-btn {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  border: none;
  border-radius: 8px;
  background: none;
  font-family: var(--vh-cond);
  font-weight: 600;
  font-size: 1rem;
  color: #20232b;
  white-space: nowrap;
  transition: color 0.2s ease, background 0.2s ease;
}
.nav-drop-btn:hover,
.nav-drop-btn[aria-expanded="true"] { color: var(--vh-blue); background: var(--vh-blue-tint); }
/* `aria-current="page"` is the right marker for a link but says nothing useful
   on a <button> that opens a menu, so the two dropdown triggers carry a class
   instead. Set by scripts/apply-site-chrome.js per page. */
.nav-drop-btn.is-current {
  background: var(--vh-blue-tint);
  color: var(--vh-blue);
  font-weight: 700;
}
.nav-drop-btn svg { width: 11px; height: 11px; transition: transform 0.25s ease; }
.nav-drop-btn[aria-expanded="true"] svg { transform: rotate(180deg); }

.mega-menu { display: none; }
.mega-menu.open { display: block; }

.mega-title {
  font-size: 0.78rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  padding-bottom: 8px;
  margin-bottom: 8px;
  border-bottom: 1px solid var(--border);
}

.mega-group ul li a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 9px 10px;
  border-radius: 8px;
  border-bottom: none;
  font-size: 0.92rem;
  font-weight: 500;
  color: var(--text);
  transition: color 0.2s ease, background 0.2s ease;
}
.mega-group ul li a:hover { color: var(--primary); background: var(--primary-light); }
.mega-arrow {
  opacity: 0;
  transform: translateX(-4px);
  transition: opacity 0.2s ease, transform 0.2s ease;
  color: var(--primary);
}
.mega-group ul li a:hover .mega-arrow { opacity: 1; transform: translateX(0); }

/* Category rail (left side of the two-pane Courses menu) */
.mega-cat {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  width: 100%;
  padding: 11px 14px;
  border: none;
  border-radius: 10px;
  background: none;
  font-family: inherit;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--text);
  text-align: left;
  cursor: pointer;
  transition: background 0.2s ease, color 0.2s ease;
}
.mega-cat:hover, .mega-cat.active { background: var(--primary-light); color: var(--primary); }
.cat-arrow { opacity: 0.55; font-size: 1.1em; }

/* Desktop: floating panel under the header.
   `absolute` inside the sticky header rather than `fixed` to the viewport — a
   sticky element is a positioned element, so this tracks the header itself and
   the promo strip above it cannot knock the panel 38px out of line (§34). The
   header spans the full viewport width with no left border or padding, so the
   viewport-space `left` that script.js computes is still the right value. */
@media (min-width: 993px) {
  .mega-menu.open {
    position: absolute;
    top: 100%;
    left: 0;
    width: min(430px, 96%);
    background: #fff;
    border: 1px solid var(--border);
    border-top: none;
    border-radius: 0 0 18px 18px;
    /* left is set by script.js so the panel lines up under its button */
    box-shadow: var(--shadow-lg);
    padding: 14px 18px 16px;
    z-index: 99;
  }
  .mega-inner.mega-split {
    display: grid;
    grid-template-columns: 150px 1fr;
    gap: 14px;
  }
  .mega-cats {
    display: flex;
    flex-direction: column;
    gap: 2px;
    border-right: 1px solid var(--border);
    padding-right: 10px;
  }
  .mega-cat { padding: 9px 11px; font-size: 0.92rem; }
  .mega-group ul li a { padding: 8px 10px; font-size: 0.9rem; }
  .mega-title { padding-bottom: 6px; margin-bottom: 4px; }
  .mega-panel { display: none; }
  .mega-panel.active { display: block; }

  /* Small flat dropdown (e.g. Test Series) — anchored under its button by JS.
     Shrunk from 280px (owner, 16 Aug 2026): with the label now just "Test
     Series", 280px left a lot of unused white space around two one-line
     items. 200px still clears "Test Series →" at .mega-group's 0.9rem/8px-10px
     padding with room to spare. */
  .mega-menu-sm.open {
    left: auto;
    transform: none;
    width: 200px;
    border-radius: 0 0 14px 14px;
    padding: 10px;
  }
  .mega-menu-sm .mega-inner { display: block; }
}

/* Compact header range */
@media (max-width: 1120px) and (min-width: 993px) {
  .nav-drop-btn { padding: 8px 10px; font-size: 0.88rem; }
}

/* =========================================================
   COURSE DETAIL PAGE (e.g. Foundation Class 9)
   ========================================================= */
.course-hero {
  width: min(960px, 92%);
  margin: 20px auto 0;
  border-radius: 18px;
  overflow: hidden;
  background: linear-gradient(120deg, #0e2a66 0%, #1a2ef0 60%, #2f74ff 100%);
  color: #fff;
  padding: 44px 48px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 28px;
}
.course-hero-badge {
  display: inline-block;
  background: rgba(255, 255, 255, 0.18);
  border: 1px solid rgba(255, 255, 255, 0.35);
  border-radius: 999px;
  padding: 5px 16px;
  font-size: 0.82rem;
  font-weight: 600;
}
.course-hero h1 { font-size: clamp(1.6rem, 3.4vw, 2.4rem); font-weight: 800; margin: 14px 0 8px; line-height: 1.2; }
.course-hero p { color: rgba(255, 255, 255, 0.88); font-size: 1rem; }
.course-hero-art { flex-shrink: 0; width: 130px; height: 130px; border-radius: 50%; background: rgba(255, 255, 255, 0.14); display: grid; place-items: center; padding: 30px; }

.breadcrumb {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  font-size: 0.85rem;
  color: var(--muted);
  margin: 22px 0 6px;
}
.breadcrumb a { color: var(--muted); transition: color 0.2s ease; }
.breadcrumb a:hover { color: var(--primary); }
.breadcrumb .crumb-sep { opacity: 0.6; }
.breadcrumb .current { color: var(--text); font-weight: 600; }

.course-page-title { font-size: clamp(1.5rem, 3vw, 2rem); font-weight: 800; letter-spacing: -0.02em; margin-bottom: 18px; }

/* board tabs */
.board-tabs { display: flex; gap: 10px; margin-bottom: 26px; }
.board-tabs button {
  padding: 9px 26px;
  border-radius: 999px;
  border: 1.5px solid var(--border);
  background: #fff;
  font-family: inherit;
  font-size: 0.92rem;
  font-weight: 600;
  color: var(--muted);
  transition: all 0.2s ease;
}
.board-tabs button:hover { border-color: var(--primary); color: var(--primary); }
.board-tabs button.active { background: var(--primary-light); border-color: var(--primary); color: var(--primary); }

/* batch card */
.batch-card {
  max-width: 520px;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 24px 26px;
}
.batch-card-top { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
.live-badge {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  background: var(--dark);
  color: #fff;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  padding: 6px 14px;
  border-radius: 999px;
}
.live-dot { width: 8px; height: 8px; border-radius: 50%; background: #ff3b3b; animation: livePulse 1.6s ease infinite; }
@keyframes livePulse { 50% { opacity: 0.35; } }
.batch-chip {
  background: var(--tint-peach);
  color: var(--accent-deep);
  font-size: 0.75rem;
  font-weight: 700;
  padding: 5px 12px;
  border-radius: 999px;
}
.batch-chip.urgent { background: var(--accent-deep); color: #fff; }
.batch-card h3 { font-size: 1.15rem; margin-bottom: 4px; }

/* tick list inside a batch card */
.batch-points { margin: 14px 0 18px; }
.batch-points li {
  position: relative;
  padding-left: 26px;
  margin-bottom: 9px;
  color: var(--muted);
  font-size: 0.92rem;
  line-height: 1.55;
}
.batch-points li::before {
  content: "✓";
  position: absolute;
  left: 0;
  top: 0;
  color: var(--primary);
  font-weight: 700;
}

.batch-sub { color: var(--muted); font-size: 0.88rem; margin-bottom: 16px; }
.batch-meta { display: flex; flex-direction: column; gap: 10px; margin-bottom: 18px; }
.batch-meta li { display: flex; align-items: center; gap: 10px; font-size: 0.92rem; font-weight: 500; }
.batch-meta .bm-icon {
  width: 34px;
  height: 34px;
  border-radius: 10px;
  background: var(--primary-light);
  color: var(--primary);
  display: grid;
  place-items: center;
  padding: 8px;
  flex-shrink: 0;
}
.batch-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  border-top: 1px solid var(--border);
  padding-top: 16px;
}
.reg-fee span { display: block; font-size: 0.78rem; color: var(--muted); font-weight: 500; }
.reg-fee strong { font-size: 1.3rem; color: var(--dark); }

/* long-form description */
.course-desc { max-width: 900px; margin-inline: auto; }
.course-desc h2 { font-size: clamp(1.25rem, 2.4vw, 1.6rem); font-weight: 700; line-height: 1.35; margin-bottom: 14px; }
.course-desc > p { color: var(--muted); margin-bottom: 10px; }
.course-desc h3 {
  font-size: 1.15rem;
  font-weight: 700;
  margin: 34px 0 18px;
  padding-left: 12px;
  border-left: 4px solid var(--primary);
}
.check-list { display: grid; grid-template-columns: 1fr 1fr; gap: 14px 26px; }
.check-list li {
  position: relative;
  padding-left: 32px;
  font-size: 0.93rem;
  color: var(--muted);
  line-height: 1.6;
}
.check-list li::before {
  content: "✓";
  position: absolute;
  left: 0;
  top: 2px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--primary-light);
  color: var(--primary);
  font-size: 0.8rem;
  font-weight: 700;
  display: grid;
  place-items: center;
}
.check-list li strong { color: var(--text); }

/* counselling section */
.counselling { background: var(--bg-soft); }
.counselling .callback-form { max-width: 560px; margin-inline: auto; }

/* ---------- course detail page ---------- */
.live-pill {
  display: inline-block;
  background: #e5f7ee;
  color: #14804a;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  padding: 6px 16px;
  border-radius: 999px;
}
.detail-layout {
  display: grid;
  grid-template-columns: 1fr 330px;
  gap: 28px;
  align-items: start;
  margin-top: 18px;
}
.detail-card {
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 26px 28px;
}
.detail-title { font-size: clamp(1.3rem, 2.6vw, 1.7rem); font-weight: 800; margin: 12px 0 4px; letter-spacing: -0.01em; }
.detail-meta { color: var(--muted); font-weight: 500; margin-bottom: 6px; }
.detail-row { display: flex; align-items: flex-start; gap: 12px; margin-top: 18px; }
.detail-row .bm-icon { margin-top: 2px; }
.detail-row small { display: block; color: var(--muted); font-size: 0.8rem; margin-bottom: 2px; }
.detail-row p { font-weight: 600; font-size: 0.95rem; }

.enroll-rail {
  position: sticky;
  top: calc(var(--header-h) + 16px);
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  padding: 24px;
}
.enroll-rail .batch-meta { margin: 16px 0; }
.enroll-note { font-size: 0.8rem; color: var(--muted); text-align: center; margin-top: 10px; }
.enroll-notice {
  margin-top: 12px;
  background: #e5f7ee;
  color: #14804a;
  font-weight: 500;
  font-size: 0.88rem;
  padding: 12px 14px;
  border-radius: 10px;
  text-align: center;
}

.check-list.single { grid-template-columns: 1fr; }
.about-group { margin-bottom: 6px; }

/* demo video slot */
.video-frame {
  aspect-ratio: 16 / 9;
  border-radius: var(--radius);
  overflow: hidden;
  background: linear-gradient(120deg, #0e2a66 0%, #14418f 55%, #1a2ef0 100%);
  box-shadow: var(--shadow);
  display: grid;
  place-items: center;
}
.video-frame iframe, .video-frame video { width: 100%; height: 100%; display: block; border: 0; object-fit: cover; }
.video-placeholder { text-align: center; color: #fff; }
.play-circle {
  width: 72px;
  height: 72px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.16);
  border: 2px solid rgba(255, 255, 255, 0.55);
  display: grid;
  place-items: center;
  font-size: 1.5rem;
  padding-left: 6px;
  margin: 0 auto 14px;
  transition: transform 0.25s ease, background 0.25s ease;
}
.video-frame:hover .play-circle { transform: scale(1.08); background: rgba(255, 255, 255, 0.28); }
.video-placeholder p { font-weight: 600; opacity: 0.9; }

/* two batch cards side by side (test series + "chosen by our champs") */
.ultimate-home { padding-top: 24px; padding-bottom: 72px; }
.ultimate-home-inner { display: grid; grid-template-columns: minmax(0, 1fr) 410px; gap: 86px; align-items: center; min-height: 510px; }
.ultimate-home-inner > div:first-child { padding-left: 2px; }
.ultimate-kicker { color: var(--primary); font-size: .78rem; font-weight: 800; letter-spacing: .2em; margin-bottom: 22px; }
.ultimate-home .section-title { font-size: clamp(2.2rem, 4vw, 3rem); margin-bottom: 12px; }
.ultimate-home-copy { max-width: 690px; color: var(--muted); font-size: 1.12rem; line-height: 1.65; }
.ultimate-promo-card { border-radius: 20px; padding: 28px 25px 25px; color: #fff; background: linear-gradient(155deg,#2875ef,#0c50d8); box-shadow: 0 18px 42px rgba(26,87,206,.24); }
.ultimate-best { display: inline-block; background: #ffd42e; color: #102556; border-radius: 999px; padding: 4px 9px; font-size: .66rem; font-weight: 800; }
.ultimate-promo-card h3 { margin: 25px 0 10px; font-size: 1.45rem; }
.ultimate-pills { display: flex; gap: 6px; margin-bottom: 10px; }
.ultimate-pills span { padding: 3px 9px; border-radius: 999px; background: rgba(255,255,255,.2); font-size: .65rem; font-weight: 700; }
.ultimate-promo-card > strong { display: block; font-size: 1.34rem; margin-top: 12px; }
.ultimate-promo-card > small { display: block; opacity: .9; }
.ultimate-promo-card ul { list-style: none; margin: 20px 0; padding: 0; font-size: .78rem; line-height: 1.45; }
.ultimate-promo-card li + li { margin-top: 6px; }
.ultimate-prices { display: flex; justify-content: space-between; gap: 8px; margin-bottom: 22px; font-size: .68rem; }
.ultimate-prices span { display: grid; gap: 2px; }
.ultimate-prices s { opacity: .7; }
.ultimate-prices b { font-size: .8rem; }
.ultimate-promo-card .btn { width: 100%; background: #0b4cd7; border: 1px solid rgba(255,255,255,.6); font-size: .82rem; padding: 13px 14px; }
@media (max-width: 900px) { .ultimate-home-inner { grid-template-columns: 1fr 350px; gap: 36px; } }
@media (max-width: 760px) { .ultimate-home { padding-top: 48px; padding-bottom: 48px; } .ultimate-home-inner { grid-template-columns: 1fr; gap: 30px; min-height: 0; } .ultimate-promo-card { max-width: 410px; } }

/* Three-column Ultimate PYQ product card. The outer card fills its parent;
   the inner wrapper owns the strict 12-column desktop composition. */
.ultimate-product-card { width: 100%; margin: 0; border: 1px solid #e5e7eb; border-radius: 18px; background: #fff; box-shadow: 0 8px 26px rgba(15, 23, 42, .06); overflow: hidden; }
.ultimate-product-inner { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: 32px; align-items: center; padding: 20px 40px; }
.ultimate-product-copy { grid-column: span 4; min-width: 0; align-self: center; }
.ultimate-product-copy .ultimate-best { color: #2563eb; background: #eff6ff; border: 1px solid #bfdbfe; letter-spacing: .08em; font-size: .64rem; padding: 6px 10px; }
.ultimate-product-copy .ultimate-best span { color: #2563eb; font-size: .74rem; }
.ultimate-product-copy h2 { margin: 18px 0 2px; color: #1e293b; font-size: clamp(1.9rem, 3vw, 2.65rem); line-height: 1.1; letter-spacing: -.04em; }
.ultimate-product-copy h2 span { color: #2563eb; }
.ultimate-product-copy p { margin: 0 0 20px; color: #475569; font-size: 1rem; }
.ultimate-feature-pills { display: grid; gap: 9px; }
.ultimate-feature-pills span { display: inline-flex; align-items: center; gap: 8px; width: max-content; max-width: 100%; padding: 7px 11px; border: 1px solid #e2e8f0; border-radius: 999px; color: #334155; background: #fff; font-size: .74rem; }
.ultimate-feature-pills span span { border: 0; padding: 0; color: #2563eb; font-size: .86rem; }
.ultimate-product-art { grid-column: span 4; position: relative; display: flex; align-items: center; justify-content: center; height: 360px; overflow: hidden; isolation: isolate; }
.ultimate-art-glow { position: absolute; width: 340px; height: 340px; border-radius: 50%; background: radial-gradient(circle, #dbeafe 0%, #eff6ff 48%, rgba(239, 246, 255, 0) 74%); filter: blur(3px); z-index: 0; }
.ultimate-product-art img { position: absolute; z-index: 1; top: 50%; left: 50%; display: block; width: min(760px, 210%); max-width: none; height: auto; transform: translate(-50%, -50%) scale(1.04); mix-blend-mode: multiply; filter: drop-shadow(0 14px 16px rgba(37, 99, 235, .16)); -webkit-mask-image: radial-gradient(ellipse 48% 50% at center, #000 48%, rgba(0, 0, 0, .88) 62%, transparent 82%); mask-image: radial-gradient(ellipse 48% 50% at center, #000 48%, rgba(0, 0, 0, .88) 62%, transparent 82%); }
.ultimate-product-pricing { grid-column: span 4; min-width: 0; display: flex; flex-direction: column; align-self: stretch; justify-content: center; padding-left: 32px; border-left: 1px solid #e5e7eb; }
.ultimate-price-block { display: grid; gap: 3px; }.ultimate-price-block strong { color: #2563eb; font-size: .72rem; letter-spacing: .1em; }.ultimate-price-block s { color: #94a3b8; font-size: .75rem; }.ultimate-price-block b { color: #2563eb; font-size: 1.75rem; line-height: 1.1; }.ultimate-price-block b small { color: #64748b; font-size: .72rem; font-weight: 500; }
.ultimate-price-divider { height: 1px; margin: 17px 0; background: #e5e7eb; }
.ultimate-product-pricing .btn { margin-top: 22px; width: 100%; padding: 12px 14px; font-size: .78rem; }
@media (max-width: 850px) { .ultimate-product-inner { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px; padding: 24px 30px; }.ultimate-product-art { height: 320px; }.ultimate-product-pricing { grid-column: 1 / -1; border-left: 0; border-top: 1px solid #e5e7eb; padding: 22px 0 0; display: grid; grid-template-columns: 1fr auto 1fr; gap: 16px; align-items: center; }.ultimate-price-divider { width: 1px; height: 70px; margin: 0; }.ultimate-product-pricing .btn { grid-column: 1 / -1; margin-top: 2px; } }
@media (max-width: 560px) { .ultimate-product-inner { grid-template-columns: 1fr; gap: 22px; padding: 22px 20px; }.ultimate-product-copy { grid-column: auto; }.ultimate-product-art { grid-column: auto; order: 2; height: 270px; }.ultimate-product-pricing { grid-column: auto; order: 3; display: flex; border-top: 1px solid #e5e7eb; padding-top: 18px; }.ultimate-price-divider { width: 100%; height: 1px; margin: 14px 0; }.ultimate-product-pricing .btn { margin-top: 16px; } }

.ts-grid, .champs-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 24px;
  align-items: stretch;
  max-width: 820px;
}
.champs-grid { margin-inline: auto; }
.ts-grid .batch-card, .champs-grid .batch-card { max-width: none; }
.champs-grid .batch-card { display: flex; flex-direction: column; }
.champs-grid .batch-points { flex: 1; }
@media (max-width: 992px) {
  .ts-grid, .champs-grid { grid-template-columns: 1fr; max-width: 520px; margin-inline: auto; }
}

/* neutral counterpart to .live-badge (test series aren't live classes) */
.count-badge {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  background: var(--dark);
  color: #fff;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  padding: 6px 14px;
  border-radius: 999px;
}

/* =========================================================
   TEST SERIES HUBS + ULTIMATE PYQs
   ========================================================= */
.ts-hub { padding-top: 2px; padding-bottom: 72px; }
.hub-lede { max-width: 700px; color: var(--muted); line-height: 1.7; margin: -4px 0 26px; }
/* TWO products: Premium Test Series and PYQ Vault. A third card was added for
   free mocks on 8 Aug and removed the same day — the free tests are a section
   of the Premium page, not a product. */
.product-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px; max-width: 920px; }
.product-card {
  min-height: 330px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 18px;
  box-shadow: var(--shadow);
  padding: 30px;
}
.product-card-premium { border-top: 4px solid var(--primary); }
.product-card-pyq { border-top: 4px solid var(--dark); }
.product-kicker { color: var(--primary); font-weight: 800; font-size: 0.73rem; letter-spacing: 0.1em; }
.product-card h3 { font-size: clamp(1.4rem, 2.2vw, 1.8rem); margin: 12px 0 10px; letter-spacing: -0.025em; }
.product-card > p { color: var(--muted); line-height: 1.65; }
.product-card ul { margin: 20px 0 26px; color: var(--muted); }
.product-card li { position: relative; padding-left: 20px; margin: 8px 0; font-size: 0.92rem; }
.product-card li::before { content: "•"; position: absolute; left: 2px; color: var(--primary); font-weight: 800; }
.product-card .btn { margin-top: auto; }
.exam-grid { max-width: 760px; }
.exam-card {
  min-height: 230px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: flex-start;
  padding: 28px;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 16px;
  box-shadow: var(--shadow);
  transition: transform 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease;
}
.exam-card:hover { transform: translateY(-3px); border-color: var(--primary); box-shadow: var(--shadow-lg); }
.exam-card span { color: var(--primary); font-size: 0.8rem; font-weight: 800; letter-spacing: 0.12em; text-transform: uppercase; }
.exam-card strong { color: var(--text); font-size: 1.45rem; line-height: 1.2; margin: 10px 0; }
.exam-card small { color: var(--muted); font-size: 0.92rem; }
.exam-card b { color: var(--primary); margin-top: auto; font-size: 0.92rem; }
.series-catalog { max-width: 900px; }
.series-card { display: flex; flex-direction: column; }
.series-card .batch-foot { margin-top: auto; }
.series-exam { color: var(--primary); font-size: 0.77rem; font-weight: 700; letter-spacing: 0.08em; margin-bottom: 6px; text-transform: uppercase; }
.series-ready { color: var(--muted); font-size: 0.84rem; font-weight: 600; }
.series-message { color: var(--muted); background: var(--bg-soft); border-radius: 12px; padding: 18px 20px; }
.series-message.error { color: #a12b2b; background: #fff0f0; }

.pyq-auth, .pyq-form {
  max-width: 920px;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 18px;
  box-shadow: var(--shadow);
  padding: 28px;
}
.pyq-auth h2 { font-size: 1.25rem; margin-bottom: 8px; }
.pyq-auth p { color: var(--muted); margin-bottom: 18px; }
.pyq-row { display: grid; gap: 7px; max-width: 360px; margin-bottom: 24px; }
.pyq-row label, .pyq-modes legend { color: var(--text); font-size: 0.88rem; font-weight: 700; }
.pyq-row select {
  width: 100%;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: #fff;
  color: var(--text);
  font: inherit;
  padding: 11px 12px;
}
.pyq-modes { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; border: 0; padding: 0; margin: 0 0 26px; }
.pyq-modes legend { grid-column: 1 / -1; margin-bottom: 2px; }
.pyq-mode { position: relative; display: grid; gap: 5px; min-height: 128px; cursor: pointer; border: 1px solid var(--border); border-radius: 12px; padding: 18px; transition: border-color 0.2s ease, background 0.2s ease, box-shadow 0.2s ease; }
.pyq-mode input { position: absolute; opacity: 0; pointer-events: none; }
.pyq-mode.selected { border-color: var(--primary); background: var(--primary-light); box-shadow: inset 0 0 0 1px var(--primary); }
.pyq-mode strong { color: var(--text); font-size: 0.98rem; }
.pyq-mode span { color: var(--muted); font-size: 0.84rem; line-height: 1.5; }
.pyq-chapters-panel { border-top: 1px solid var(--border); padding-top: 24px; margin-bottom: 25px; }
.pyq-panel-head { display: flex; align-items: start; justify-content: space-between; gap: 16px; margin-bottom: 18px; }
.pyq-panel-head h2 { font-size: 1.08rem; margin-bottom: 4px; }
.pyq-panel-head p { color: var(--muted); font-size: 0.88rem; line-height: 1.5; }
.pyq-panel-head > span { flex-shrink: 0; color: var(--primary); background: var(--primary-light); border-radius: 999px; font-size: 0.75rem; font-weight: 700; padding: 5px 10px; }
.pyq-subject + .pyq-subject { margin-top: 22px; }
.pyq-subject h3 { font-size: 0.92rem; margin-bottom: 10px; }
.pyq-chapter-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 9px; }
.pyq-chapter { display: grid; grid-template-columns: auto 1fr; gap: 2px 8px; align-items: start; cursor: pointer; border: 1px solid var(--border); border-radius: 9px; padding: 10px; color: var(--text); font-size: 0.82rem; line-height: 1.35; }
.pyq-chapter input { grid-row: 1 / span 2; margin-top: 3px; accent-color: var(--primary); }
.pyq-chapter small { grid-column: 2; color: var(--muted); font-size: 0.72rem; }
.pyq-status { max-width: 640px; border-radius: 9px; background: var(--bg-soft); color: var(--muted); font-size: 0.86rem; line-height: 1.5; padding: 11px 13px; margin-bottom: 16px; }
.pyq-status.error { background: #fff0f0; color: #a12b2b; }

@media (max-width: 760px) {
  .product-grid, .pyq-modes { grid-template-columns: 1fr; }
  .product-card { min-height: 0; padding: 24px; }
  .pyq-auth, .pyq-form { padding: 20px; }
  .pyq-chapter-grid { grid-template-columns: 1fr; }
}

/* Ultimate PYQs - white subject-first workspace */
#pyqBuilder.ts-hub { max-width: 1080px; padding-top: 8px; background: #fff; }
#pyqBuilder .breadcrumb { margin-bottom: 14px; }
.pyq-showcase {
  position: relative;
  min-height: 0;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 24px;
  margin: 0 0 18px;
  padding: 10px 400px 10px 2px;
}
.pyq-title-row { display: flex; align-items: center; }
.pyq-title-row h1 { color: #17382c; font-size: clamp(1.65rem, 3vw, 2.25rem); font-weight: 800; letter-spacing: -0.04em; }
.pyq-illustration { position: absolute; top: -28px; right: 12px; width: min(390px, 32vw); height: auto; }
#pyqBuilder .pyq-auth, #pyqBuilder .pyq-form { max-width: none; background: #fff; border: 0; border-radius: 0; box-shadow: none; padding: 0; }
#pyqBuilder .pyq-auth { padding: 26px 0; }
.pyq-paywall { margin: 12px 0 28px; max-width: 720px; }
.pyq-paywall h2 { color: #17382c; font-size: 1.05rem; margin-bottom: 12px; }
/* One block per exam. A visitor who owns nothing sees JEE and NEET stacked
   here, because the exam chips are hidden with the form in that state. */
.pyq-vault-block + .pyq-vault-block { margin-top: 26px; }
.pyq-plans { display: grid; grid-template-columns: repeat(2,minmax(0,1fr)); gap: 12px; }
.pyq-plan {
  position: relative; display: grid; gap: 4px; width: 100%; text-align: left;
  border: 1px solid #c3ddd0; border-radius: 10px; padding: 16px;
  color: #254537; background: #fff; font: inherit; cursor: pointer;
}
.pyq-plan.featured { border-color: #4d9d6b; box-shadow: inset 0 0 0 1px #4d9d6b; background: #f0faf3; }
.pyq-plan strong { font-size: 1.15rem; }.pyq-plan strong span { font-size: .72rem; font-weight: 500; }.pyq-plan small { color: #6b8176; }
/* Discount tag, pinned to the card corner instead of read as plain text. */
.pyq-plan-badge {
  position: absolute; top: -8px; right: -8px;
  background: #e0342c; color: #fff; font-size: .68rem; font-weight: 800;
  padding: 3px 9px; border-radius: 999px; letter-spacing: .02em;
  box-shadow: 0 1px 3px rgba(0,0,0,.18);
}
@media (max-width: 560px) { .pyq-plans { grid-template-columns: 1fr; } }
/* A click opens this as its own overlay, not a panel pushed into the page
   flow below the cards. */
.pyq-plan-modal { position: fixed; inset: 0; z-index: 200; display: grid; place-items: center; padding: 20px; }
.pyq-plan-modal[hidden] { display: none; }
.pyq-plan-modal-backdrop { position: absolute; inset: 0; background: rgba(15,30,23,.55); }
.pyq-plan-modal-card {
  position: relative; z-index: 1; width: min(480px, 100%); max-height: 85vh; overflow-y: auto;
  background: #fff; border-radius: 14px; padding: 28px 24px 24px;
  box-shadow: 0 24px 60px rgba(0,0,0,.28); animation: pyqPlanModalIn .18s ease;
}
.pyq-plan-modal-close {
  position: absolute; top: 12px; right: 12px; width: 30px; height: 30px;
  border-radius: 999px; border: 0; background: #f0f4f2; color: #254537;
  font-size: 1.3rem; line-height: 1; cursor: pointer;
}
.pyq-plan-modal-body h3 { margin: 0 26px 10px 0; color: #17382c; font-size: 1.1rem; }
.pyq-plan-modal-body p { margin: 0 0 10px; font-size: .87rem; line-height: 1.6; color: #3a5548; }
.pyq-plan-modal-body p:last-of-type { margin-bottom: 0; }
.pyq-plan-modal-body b { color: #17382c; }
.pyq-plan-modal-body .pyq-plan-fit {
  margin: 14px 0 0; padding: 10px 14px; border-radius: 8px;
  background: #f0faf3; border: 1px dashed #b7dcc4; font-size: .82rem; color: #2e5c41;
}
.pyq-plan-modal-body .pyq-plan-fit b { color: #1f4a30; }
.pyq-plan-modal-body .btn { margin-top: 18px; width: 100%; justify-content: center; }
@keyframes pyqPlanModalIn { from { opacity: 0; transform: translateY(8px) scale(.98); } to { opacity: 1; transform: translateY(0) scale(1); } }
/* Shown in place of the format summary when the selected mode's tier
   (Standard vs Practice) isn't usable yet — not owned, or Standard's
   25-paper cap is used up. Same dashed-border "locked" language as
   .tsd-lockedbar elsewhere on the site. */
.pyq-tier-gate.is-locked {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  margin: 4px 0 18px; padding: 14px 16px;
  border: 1px dashed #c3ddd0; border-radius: 12px;
  background: #f4f9f6; color: #4c6b5c; font-size: .86rem;
}
.pyq-tier-gate.is-locked p { margin: 0; flex: 1 1 220px; }
.pyq-tier-gate.is-locked b { color: #17382c; }
.pyq-tier-gate.is-locked .btn { flex: none; }
#pyqBuilder .pyq-row { max-width: 410px; margin-bottom: 22px; }
#pyqBuilder .pyq-row label, #pyqBuilder .pyq-modes legend { color: #254537; font-size: 0.82rem; font-weight: 700; }
#pyqBuilder .pyq-row select { border-color: #c3ddd0; border-radius: 8px; background: #fff; color: #294a3a; font-size: 0.86rem; padding: 10px 12px; }
#pyqBuilder .pyq-row select:focus { outline: 2px solid #7db996; outline-offset: 1px; border-color: #6caf86; }
#pyqBuilder .pyq-custom-subjects { max-width: 930px; border: 0; padding: 0; margin: -8px 0 22px; }
#pyqBuilder .pyq-custom-subjects legend { color: #254537; font-size: 0.82rem; font-weight: 700; margin-bottom: 8px; }
#pyqBuilder .pyq-custom-subject-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; }
#pyqBuilder .pyq-custom-subject { display: flex; align-items: center; gap: 8px; min-height: 42px; cursor: pointer; border: 1px solid #d7e9de; border-radius: 7px; padding: 9px 11px; color: #315342; font-size: 0.76rem; background: #fff; }
#pyqBuilder .pyq-custom-subject input { width: 15px; height: 15px; margin: 0; accent-color: #58a775; }
#pyqBuilder .pyq-custom-subject:has(input:checked) { border-color: #5ba979; background: #ecf8ef; box-shadow: inset 0 0 0 1px #5ba979; }
#pyqBuilder .pyq-modes { max-width: 930px; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; margin-bottom: 22px; }
#pyqBuilder .pyq-modes legend { margin-bottom: 5px; }
#pyqBuilder .pyq-mode { min-height: 132px; gap: 7px; border-radius: 9px; border-color: #d4e7dc; padding: 18px; }
#pyqBuilder .pyq-mode-standard { background: #f5f1ff; border-color: #e2d7f5; color: #8764bb; }
#pyqBuilder .pyq-mode-custom { background: #fff8ef; border-color: #f2d9b8; color: #bd7a28; }
#pyqBuilder .pyq-mode-chapters { background: #f1fbf4; color: #4a9b67; }
#pyqBuilder .pyq-mode.selected { border-color: #5ba979; background: #ecf8ef; box-shadow: inset 0 0 0 1px #5ba979; }
#pyqBuilder .pyq-mode-standard.selected { border-color: #8b69bd; background: #f4edff; box-shadow: inset 0 0 0 1px #8b69bd; }
#pyqBuilder .pyq-mode-custom.selected { border-color: #db9b49; background: #fff3e3; box-shadow: inset 0 0 0 1px #db9b49; }
#pyqBuilder .pyq-mode-icon { position: relative; display: block; width: 31px; height: 31px; overflow: hidden; border-radius: 7px; background: #fff; }
#pyqBuilder .pyq-mode-icon img { position: absolute; top: 50%; left: 50%; width: 120px; max-width: none; height: auto; transform: translate(-50%, -50%); }
#pyqBuilder .pyq-mode strong { color: #254537; font-size: 0.93rem; }
#pyqBuilder .pyq-mode > span:last-child { color: #6b8176; font-size: 0.76rem; line-height: 1.45; }
#pyqBuilder .pyq-format-summary { max-width: 930px; border-top: 1px solid #dcece3; padding-top: 19px; margin: 0 0 22px; }
#pyqBuilder .pyq-format-head { display: flex; align-items: start; justify-content: space-between; gap: 16px; margin-bottom: 12px; }
#pyqBuilder .pyq-format-head h2 { color: #254537; font-size: 0.9rem; margin-bottom: 4px; }
#pyqBuilder .pyq-format-head p { color: #6b8176; font-size: 0.75rem; line-height: 1.5; }
#pyqBuilder .pyq-format-head > span { flex: 0 0 auto; color: #4a9a67; background: #eef9f1; border-radius: 999px; font-size: 0.65rem; font-weight: 700; padding: 4px 8px; }
#pyqBuilder .pyq-format-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
#pyqBuilder .pyq-format-row { display: grid; gap: 2px; border: 1px solid #d7e9de; border-radius: 7px; padding: 8px 10px; background: #fff; }
#pyqBuilder .pyq-format-row strong { color: #315342; font-size: 0.75rem; }
#pyqBuilder .pyq-format-row span { color: #6b8176; font-size: 0.68rem; }
#pyqBuilder .pyq-format-row b { color: #2e8c55; font-size: 0.68rem; }
#pyqBuilder .pyq-chapter-subject { margin-top: -2px; }
#pyqBuilder .pyq-chapters-panel { max-width: 930px; border-top-color: #dcece3; padding-top: 19px; margin-bottom: 22px; }
#pyqBuilder .pyq-question-counts { max-width: 930px; border-top: 1px solid #dcece3; padding-top: 19px; margin-bottom: 22px; }
#pyqBuilder .pyq-question-count-list { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
#pyqBuilder .pyq-question-count { display: grid; gap: 6px; border: 1px solid #d7e9de; border-radius: 7px; padding: 10px; color: #315342; font-size: 0.76rem; }
#pyqBuilder .pyq-question-count input { width: 100%; border: 1px solid #c3ddd0; border-radius: 7px; background: #fff; color: #294a3a; font: inherit; padding: 9px 10px; }
#pyqBuilder .pyq-question-count input:focus { outline: 2px solid #7db996; outline-offset: 1px; border-color: #6caf86; }
#pyqBuilder .pyq-panel-head { margin-bottom: 13px; }
#pyqBuilder .pyq-panel-head h2 { color: #254537; font-size: 0.9rem; }
#pyqBuilder .pyq-panel-head p { color: #6b8176; font-size: 0.75rem; }
#pyqBuilder .pyq-panel-head > span { color: #4a9a67; background: #eef9f1; font-size: 0.65rem; padding: 4px 8px; }
#pyqBuilder .pyq-chapter-grid { gap: 8px; }
#pyqBuilder .pyq-chapter { min-height: 0; grid-template-columns: 16px minmax(0, 1fr); align-items: center; border-color: #d7e9de; border-radius: 7px; background: #fff; padding: 7px 10px; color: #315342; font-size: 0.72rem; line-height: 1.25; }
#pyqBuilder .pyq-chapter:hover { border-color: #86c09d; background: #f8fffa; }
#pyqBuilder .pyq-chapter input { width: 16px; height: 16px; margin: 0; align-self: center; accent-color: #58a775; }
#pyqBuilder .pyq-empty { color: #6b8176; font-size: 0.76rem; }
#pyqBuilder .pyq-status { background: #f4fbf6; color: #547466; }

@media (max-width: 760px) {
  .pyq-showcase { min-height: 112px; padding: 4px 130px 4px 2px; }
  .pyq-illustration { top: 50%; right: -8px; width: 150px; transform: translateY(-50%); }
  #pyqBuilder .pyq-custom-subject-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  #pyqBuilder .pyq-question-count-list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  #pyqBuilder .pyq-modes { grid-template-columns: 1fr; }
  #pyqBuilder .pyq-format-grid { grid-template-columns: 1fr; }
}

@media (max-width: 440px) {
  .pyq-showcase { padding-right: 0; }
  .pyq-illustration { display: none; }
  #pyqBuilder .pyq-custom-subject-grid { grid-template-columns: 1fr; }
  #pyqBuilder .pyq-question-count-list { grid-template-columns: 1fr; }
}

/* =========================================================
   EDITORIAL — long-form course/test-series writeups
   Minimal: serif display, hairline rules, no tick marks.
   ========================================================= */
.editorial { max-width: 780px; }
.ed-kicker {
  display: block;
  text-transform: uppercase;
  letter-spacing: 0.2em;
  font-size: 0.7rem;
  font-weight: 600;
  color: var(--primary);
  margin-bottom: 18px;
}
.ed-title {
  font-family: "Poppins", "Noto Sans Devanagari", "Segoe UI", system-ui, sans-serif;
  font-weight: 800;
  font-size: clamp(2.2rem, 5vw, 3.3rem);
  line-height: 1.08;
  letter-spacing: -0.01em;
  color: var(--dark);
  margin-bottom: 14px;
}
.ed-lede {
  font-size: 1.12rem;
  line-height: 1.6;
  color: var(--text);
  padding-bottom: 26px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 26px;
}
.editorial > p { color: var(--muted); font-size: 1rem; line-height: 1.75; margin-bottom: 22px; }
.ed-rule { height: 1px; background: var(--border); border: 0; margin: 52px 0 44px; }
.ed-h2 {
  font-family: "Poppins", "Noto Sans Devanagari", "Segoe UI", system-ui, sans-serif;
  font-weight: 700;
  font-size: clamp(1.6rem, 3.2vw, 2.1rem);
  line-height: 1.2;
  color: var(--dark);
  margin-top: 48px;
  margin-bottom: 18px;
}
.ed-lede + .ed-h2 { margin-top: 24px; }

/* Blog section titles lead straight into their copy; paragraph spacing stays below each paragraph. */
.ed-layout .editorial > .ed-h2 { margin-bottom: 0; }
.ed-layout .editorial > .ed-h2 + p { margin-top: 0; }

/* numbered feature blocks */
.ed-block { display: grid; grid-template-columns: 58px 1fr; gap: 24px; margin-bottom: 46px; }
.ed-num {
  font-family: "Poppins", "Noto Sans Devanagari", "Segoe UI", system-ui, sans-serif;
  font-weight: 700;
  font-size: 1.9rem;
  line-height: 1;
  color: var(--primary);
  opacity: 0.4;
  padding-top: 2px;
}
.ed-block h3 { font-size: 1.18rem; font-weight: 700; letter-spacing: -0.01em; margin-bottom: 6px; }
.ed-block > div > p { color: var(--muted); font-size: 0.97rem; line-height: 1.7; }
.ed-note { color: var(--muted); font-size: 0.92rem; font-style: italic; margin-top: 16px; }

/* item grid — hairline separators instead of bullets or ticks */
.ed-items {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 36px;
  margin-top: 18px;
}
.ed-items li {
  padding: 11px 0;
  border-top: 1px solid var(--border);
  font-size: 0.93rem;
  font-weight: 500;
  color: var(--text);
}

/* single-column variant for sentence-length items */
.ed-list { margin-top: 16px; }
.ed-list li {
  padding: 12px 0;
  border-top: 1px solid var(--border);
  font-size: 0.95rem;
  line-height: 1.65;
  color: var(--muted);
}
.ed-list li strong { color: var(--text); font-weight: 600; }

/* spec table */
.spec-table { width: 100%; border-collapse: collapse; }
.spec-table th, .spec-table td {
  text-align: left;
  padding: 15px 0;
  border-bottom: 1px solid var(--border);
  vertical-align: top;
}
.spec-table th {
  width: 40%;
  font-size: 0.74rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--muted);
  padding-right: 20px;
}
.spec-table td { font-size: 0.96rem; font-weight: 500; }
.spec-table tr:first-child th, .spec-table tr:first-child td { border-top: 1px solid var(--border); }

.ed-close { margin-top: 28px; }

@media (max-width: 620px) {
  .ed-items { grid-template-columns: 1fr; }
  .ed-block { grid-template-columns: 1fr; gap: 10px; }
  .ed-num { font-size: 1.5rem; }
  .spec-table th { width: 45%; font-size: 0.7rem; }
}

/* =========================================================
   BLOG
   ========================================================= */
.blogs-intro {
  max-width: 820px;
  padding-bottom: 26px;
  border-bottom: 1px solid var(--border);
}
.blogs-intro-kicker {
  display: block;
  color: var(--primary);
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  margin-bottom: 12px;
}
.blogs-intro h1 {
  color: var(--dark);
  font-family: "Poppins", sans-serif;
  font-size: clamp(2rem, 4vw, 3rem);
  font-weight: 800;
  line-height: 1.15;
  letter-spacing: -0.03em;
  margin-bottom: 12px;
}
.blogs-intro p {
  color: var(--muted);
  font-size: 1rem;
  line-height: 1.65;
  margin: 0;
}
.blog-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; }

.blog-card {
  display: flex;
  flex-direction: column;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 26px 24px;
  transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease;
}
.blog-card { position: relative; }
.blog-card:hover { transform: translateY(-6px); box-shadow: var(--shadow-lg); border-color: transparent; }
/* stretch the title link over the whole card so the tag, excerpt and
   "Read article" row are all clickable, not just the headline */
.blog-card h2 a::after { content: ""; position: absolute; inset: 0; }
.blog-tag {
  display: inline-block;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--primary);
  margin-bottom: 14px;
}
.blog-card h2 { font-size: 1.12rem; font-weight: 700; line-height: 1.38; margin-bottom: 10px; letter-spacing: -0.01em; }
.blog-card h2 a { color: var(--dark); }
.blog-card:hover h2 a { color: var(--primary); }
.blog-card p { color: var(--muted); font-size: 0.92rem; line-height: 1.65; flex: 1; }
.blog-read { margin-top: 18px; font-weight: 600; font-size: 0.9rem; color: var(--primary); }
.blog-read span { display: inline-block; transition: transform 0.2s ease; }
.blog-card:hover .blog-read span { transform: translateX(4px); }

/* article page */
.article-wrap { margin-inline: auto; }
.ed-layout {
  display: grid;
  grid-template-columns: minmax(0, 780px) minmax(240px, 280px);
  align-items: start;
  gap: 56px;
  max-width: 1116px;
  margin-inline: auto;
}
.ed-layout .editorial { max-width: none; }
.ed-side {
  position: sticky;
  top: calc(var(--header-h) + 24px);
  display: grid;
  gap: 18px;
}
.ed-toc,
.ed-more {
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--bg);
  padding: 20px;
}
.ed-toc h2,
.ed-more h2 {
  margin: 0 0 14px;
  color: var(--dark);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  line-height: 1.35;
  text-transform: uppercase;
}
.ed-toc ol,
.ed-more ul { margin: 0; padding: 0; list-style: none; }
.ed-toc li { border-left: 2px solid var(--border); }
.ed-toc li + li { margin-top: 7px; }
.ed-toc a {
  display: block;
  padding: 4px 0 4px 11px;
  color: var(--muted);
  font-size: 0.82rem;
  line-height: 1.45;
}
.ed-toc li.is-active { border-left-color: var(--primary); }
.ed-toc li.is-active a { color: var(--primary); font-weight: 700; }
.ed-toc a:hover { color: var(--primary); }
.ed-toc a:focus-visible,
.ed-more a:focus-visible { outline: 2px solid var(--primary); outline-offset: 3px; }
.ed-more li + li { border-top: 1px solid var(--border); margin-top: 13px; padding-top: 13px; }
.ed-more a { display: block; }
.ed-more-tag {
  display: block;
  margin-bottom: 5px;
  color: var(--primary);
  font-size: 0.63rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.ed-more-title {
  display: block;
  color: var(--dark);
  font-size: 0.86rem;
  font-weight: 600;
  line-height: 1.45;
}
.ed-more a:hover .ed-more-title { color: var(--primary); }
.editorial > ul { margin: 0 0 16px; }
.editorial > ul li {
  position: relative;
  padding-left: 20px;
  margin-bottom: 10px;
  color: var(--muted);
  line-height: 1.75;
}
.editorial > ul li::before {
  content: "";
  position: absolute;
  left: 2px;
  top: 12px;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--primary);
}
.editorial strong { color: var(--text); font-weight: 600; }

@media (max-width: 992px) { .blog-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 980px) {
  .ed-layout { grid-template-columns: minmax(0, 780px); max-width: 780px; }
  .ed-side { position: static; }
  .ed-toc { display: none; }
}
@media (max-width: 620px) {
  .blog-grid { grid-template-columns: 1fr; }
}

/* ---------- know your teachers ---------- */
.teachers-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 26px;
  max-width: 900px;
  margin-inline: auto;
}
.teacher-card { margin: 0; text-align: center; }
.teacher-photo {
  aspect-ratio: 1 / 1;
  border-radius: 16px;
  background: var(--tint-blue);
  color: var(--primary);
  display: grid;
  place-items: center;
  overflow: hidden;
  margin-bottom: 12px;
  transition: transform 0.25s ease, box-shadow 0.25s ease;
}
.teacher-card:hover .teacher-photo { transform: translateY(-4px); box-shadow: var(--shadow-lg); }
.teacher-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.teacher-photo svg { width: 46%; height: 46%; opacity: 0.5; }
.teacher-card figcaption { font-weight: 600; font-size: 0.98rem; }

@media (max-width: 860px) {
  .teachers-grid { grid-template-columns: repeat(2, 1fr); gap: 18px; }
}

/* policy strip (below course details) */
.policy-strip { background: var(--bg-soft); padding: 30px 0; margin-top: 56px; }
.policy-card {
  background: #fff;
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 22px 28px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--dark);
}
.policy-card .pc-arrow { font-size: 1.2rem; color: var(--text); }

/* link-only footer variant (course detail pages) */
.footer-grid.links { grid-template-columns: repeat(4, 1fr); }

/* ---------- register page ---------- */
.auth-wrap { min-height: calc(100vh - var(--header-h) - 120px); display: grid; place-items: center; padding: 48px 0; }
.auth-card { width: min(440px, 92vw); }
.auth-card h1 { font-size: 1.5rem; font-weight: 800; margin-bottom: 4px; }
.auth-sub { color: var(--muted); font-size: 0.92rem; margin-bottom: 22px; }
.or-divider {
  display: flex;
  align-items: center;
  gap: 12px;
  color: var(--muted);
  font-size: 0.82rem;
  margin: 18px 0;
}
.or-divider::before, .or-divider::after { content: ""; flex: 1; border-top: 1px solid var(--border); }
.btn-google {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 100%;
  background: #fff;
  border: 1.5px solid var(--border);
  border-radius: 10px;
  padding: 11px;
  font-family: inherit;
  font-size: 0.93rem;
  font-weight: 600;
  color: var(--text);
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
}
.btn-google:hover { border-color: var(--primary); box-shadow: var(--shadow); }
.btn-google svg { width: 18px; height: 18px; }
.google-note { font-size: 0.78rem; color: var(--muted); text-align: center; margin-top: 8px; }
.auth-fineprint { font-size: 0.75rem; color: var(--muted); text-align: center; margin-top: 18px; line-height: 1.6; }
/* ---------- checkout / payment ---------- */
.checkout-card { width: min(560px, 92vw); }

.co-summary {
  background: var(--bg-soft);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 16px 18px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  margin-bottom: 26px;
}
.co-summary small { display: block; color: var(--muted); font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.08em; font-weight: 600; }
.co-summary strong { font-size: 0.98rem; font-weight: 600; }
.co-amount { text-align: right; flex-shrink: 0; }
.co-amount b { font-size: 1.35rem; color: var(--dark); }

.co-step { display: flex; align-items: center; gap: 10px; margin: 26px 0 14px; }
.co-step-num {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--primary);
  color: #fff;
  font-size: 0.78rem;
  font-weight: 700;
  display: grid;
  place-items: center;
  flex-shrink: 0;
}
.co-step h2 { font-size: 1rem; font-weight: 700; }

.qr-wrap { text-align: center; padding: 18px; border: 1px solid var(--border); border-radius: 12px; }
.qr-wrap img { width: min(230px, 60vw); height: auto; margin: 0 auto; border-radius: 8px; }
.qr-missing {
  display: grid;
  place-items: center;
  width: min(230px, 60vw);
  aspect-ratio: 1;
  margin: 0 auto;
  border: 2px dashed var(--border);
  border-radius: 8px;
  color: var(--muted);
  font-size: 0.85rem;
  text-align: center;
  padding: 16px;
}
.qr-hint-text { color: var(--muted); font-size: 0.85rem; margin-top: 12px; }

/* upload box */
.upload-box {
  /* a <label> is inline by default — without this its padding/border overlap
     the surrounding text instead of forming a box */
  display: block;
  border: 2px dashed var(--border);
  border-radius: 12px;
  padding: 26px 20px;
  text-align: center;
  cursor: pointer;
  transition: border-color 0.2s ease, background 0.2s ease;
}
.upload-box:hover, .upload-box.dragover { border-color: var(--primary); background: var(--primary-light); }
.upload-box svg { width: 30px; height: 30px; margin: 0 auto 10px; color: var(--primary); }
.upload-box strong { display: block; font-size: 0.95rem; margin-bottom: 4px; }
.upload-box span { color: var(--muted); font-size: 0.82rem; }
.upload-box input[type="file"] { display: none; }

.upload-preview { display: flex; align-items: center; gap: 14px; border: 1px solid var(--border); border-radius: 12px; padding: 12px; }
.upload-preview img { width: 64px; height: 64px; object-fit: cover; border-radius: 8px; flex-shrink: 0; }
.upload-preview-info { flex: 1; min-width: 0; }
.upload-preview-info strong { display: block; font-size: 0.9rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.upload-preview-info span { color: var(--muted); font-size: 0.8rem; }
.upload-remove {
  border: none;
  background: none;
  color: #e0344a;
  font-size: 0.85rem;
  font-weight: 600;
  flex-shrink: 0;
}

.co-progress { height: 6px; border-radius: 999px; background: var(--border); overflow: hidden; margin-top: 14px; }
.co-progress i { display: block; height: 100%; width: 0; background: var(--primary); transition: width 0.2s ease; }

.co-note {
  background: var(--tint-peach);
  border: 1px solid #f3d5b5;
  color: var(--accent-deep);
  border-radius: 10px;
  padding: 12px 14px;
  font-size: 0.85rem;
  line-height: 1.55;
  margin-top: 18px;
}

/* ---------- profile page ---------- */
.profile-head { text-align: center; }
.profile-avatar-fallback {
  width: 88px;
  height: 88px;
  border-radius: 50%;
  margin: 0 auto 16px;
  display: grid;
  place-items: center;
  background: var(--primary);
  color: #fff;
  font-size: 2rem;
  font-weight: 700;
}
.profile-name { font-size: 1.35rem; font-weight: 700; letter-spacing: -0.01em; }
.profile-email { color: var(--muted); font-size: 0.92rem; margin-top: 2px; }
.profile-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 12px;
  background: var(--primary-light);
  color: var(--primary);
  border-radius: 999px;
  padding: 5px 14px;
  font-size: 0.78rem;
  font-weight: 600;
}

.profile-rows { margin-top: 26px; }
.profile-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 18px;
  padding: 14px 0;
  border-top: 1px solid var(--border);
  font-size: 0.93rem;
}
.profile-row span:first-child {
  color: var(--muted);
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 600;
  flex-shrink: 0;
}
.profile-row span:last-child { font-weight: 600; text-align: right; word-break: break-word; }

.profile-links { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 24px; }
.profile-links a {
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 8px 16px;
  font-size: 0.87rem;
  font-weight: 500;
  transition: color 0.2s ease, border-color 0.2s ease, background 0.2s ease;
}
.profile-links a:hover { color: var(--primary); border-color: var(--primary); background: var(--primary-light); }

.btn-signout {
  width: 100%;
  margin-top: 28px;
  background: #fff;
  border: 1.5px solid #e0344a;
  color: #e0344a;
  border-radius: 10px;
  padding: 12px;
  font-family: inherit;
  font-size: 0.95rem;
  font-weight: 600;
  transition: background 0.2s ease, color 0.2s ease;
}
.btn-signout:hover { background: #e0344a; color: #fff; }
.btn-signout:disabled { opacity: 0.6; cursor: default; }

.auth-success { text-align: center; padding: 20px 0 6px; }
.auth-success .as-icon { font-size: 2.4rem; margin-bottom: 8px; }
.auth-success h2 { font-size: 1.25rem; margin-bottom: 6px; }
.auth-success p { color: var(--muted); font-size: 0.92rem; margin-bottom: 18px; }

@media (max-width: 992px) {
  .detail-layout { grid-template-columns: 1fr; }
  .enroll-rail { position: static; order: -1; }
}

/* footer social row */
.footer-social {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 34px 0 0;
}
.footer-social span { font-weight: 600; color: #fff; }
.footer-social a {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.1);
  display: grid;
  place-items: center;
  padding: 9px;
  color: #c6cbe0;
  transition: background 0.2s ease, color 0.2s ease, transform 0.2s ease;
}
.footer-social a:hover { background: var(--primary); color: #fff; transform: translateY(-2px); }

@media (max-width: 620px) {
  .course-hero { padding: 32px 26px; }
  .course-hero-art { display: none; }
  .check-list { grid-template-columns: 1fr; }
  .batch-foot { flex-direction: column; align-items: stretch; text-align: center; }
}

/* Mobile: in-flow accordion inside the dropdown nav */
@media (max-width: 992px) {
  .nav-drop-btn {
    width: 100%;
    justify-content: space-between;
    padding: 14px 10px;
    border-radius: 0;
    border-bottom: 1px solid var(--border);
    font-size: 0.95rem;
  }
  .mega-menu.open {
    background: var(--bg-soft);
    border-radius: 12px;
    padding: 4px 14px 14px;
    margin: 8px 0;
  }
  .mega-group { margin-top: 14px; }
  .mega-menu-sm .mega-group { margin-top: 4px; }
  .mega-arrow { opacity: 1; transform: none; }
  /* mobile: no category rail — all panels stack with their titles */
  .mega-cats { display: none; }
  .mega-panel { display: block; }
}

/* =========================================================
   TEST ENGINE
   My Tests dashboard (.mt-*), CBT player (.tp-*), result (.rs-*)
   ========================================================= */

:root {
  --q-answered: #14804a;
  --q-not-answered: #e0344a;
  --q-not-visited: #c2c8d4;
  --q-marked: #7c3aed;
  --q-answered-marked: #ec4899;
  --q-current: #1a2ef0;
}

/* ---------------------------------------------------------
   MY TESTS
   --------------------------------------------------------- */
.mt-note { color: var(--muted); margin: 18px 0; }
.mt-note-inline { color: var(--muted); }

.mt-series { margin-top: 34px; }
.mt-series-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  padding-bottom: 12px;
  border-bottom: 2px solid var(--dark);
}
.mt-series-head h2 {
  font-family: "Poppins", "Noto Sans Devanagari", "Segoe UI", system-ui, sans-serif;
  font-size: clamp(1.5rem, 3vw, 2rem);
  font-weight: 700;
  letter-spacing: -0.01em;
}
.mt-valid { font-size: 0.82rem; color: var(--muted); white-space: nowrap; }

.mt-papers { margin-top: 4px; }
.mt-paper {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding: 20px 0;
  border-bottom: 1px solid var(--border);
  flex-wrap: wrap;
}
.mt-paper-main { flex: 1 1 320px; min-width: 0; }
.mt-paper h3 { font-size: 1.05rem; font-weight: 600; }
.mt-meta { font-size: 0.85rem; color: var(--muted); margin-top: 2px; }
.mt-sub { font-size: 0.85rem; margin-top: 6px; display: flex; gap: 14px; flex-wrap: wrap; align-items: center; }
.mt-score strong { color: var(--dark); font-size: 1rem; }
.mt-review { color: var(--primary); font-weight: 600; text-decoration: underline; text-underline-offset: 3px; }
.mt-live {
  color: var(--accent-deep);
  font-weight: 600;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.mt-live::before {
  content: "";
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--accent);
  animation: mtPulse 1.6s ease-in-out infinite;
}
@keyframes mtPulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.25; } }
.mt-again { border: 1px solid var(--border); }

/* ---------------------------------------------------------
   PLAYER â€” full screen, no site chrome
   --------------------------------------------------------- */
.tp-body {
  /* The player is its own world: no sticky header, no page scroll, and no
     pull-to-refresh (which would otherwise reload the exam mid-question). */
  margin: 0;
  overscroll-behavior: none;
  background: var(--bg-soft);
}

.tp-centre {
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  text-align: center;
  padding: 32px 22px;
}
.tp-centre h1, .tp-centre h2 {
  font-family: "Poppins", "Noto Sans Devanagari", "Segoe UI", system-ui, sans-serif;
  font-weight: 700;
  font-size: clamp(1.6rem, 4vw, 2.4rem);
}
.tp-centre p { color: var(--muted); max-width: 46ch; }

.tp-spinner {
  width: 34px; height: 34px;
  border: 3px solid var(--border);
  border-top-color: var(--primary);
  border-radius: 50%;
  animation: tpSpin 0.8s linear infinite;
}
@keyframes tpSpin { to { transform: rotate(360deg); } }

/* ---- instructions ---- */
.tp-instructions { justify-content: center; }
.tp-ins-grid {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  justify-content: center;
  margin: 6px 0 4px;
}
.tp-ins-grid > div {
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 14px 26px;
  min-width: 108px;
}
.tp-ins-grid span { display: block; font-size: 1.5rem; font-weight: 700; color: var(--primary); }
.tp-ins-grid small { color: var(--muted); font-size: 0.78rem; }

.tp-ins-list {
  text-align: left;
  max-width: 60ch;
  display: grid;
  gap: 10px;
  margin: 10px 0;
}
.tp-ins-list li {
  position: relative;
  padding-left: 20px;
  font-size: 0.92rem;
  color: var(--text);
  line-height: 1.55;
}
.tp-ins-list li::before {
  content: "";
  position: absolute;
  left: 0; top: 0.62em;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--primary);
}
.tp-ins-warn {
  background: #fff6ed;
  border: 1px solid #f6d9bd;
  border-radius: 12px;
  padding: 12px 16px;
  font-size: 0.88rem;
  color: var(--accent-deep) !important;
  max-width: 60ch;
}
.tp-ins-back { color: var(--muted); font-size: 0.86rem; text-decoration: underline; text-underline-offset: 3px; }

/* ---- shell ---- */
.tp-shell {
  height: 100dvh;
  display: grid;
  grid-template-rows: auto auto 1fr auto;
  background: var(--bg-soft);
}

.tp-top {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 10px 18px;
  background: #fff;
  border-bottom: 1px solid var(--border);
}
.tp-top-left { flex: 1 1 auto; min-width: 0; }
.tp-test-name {
  font-weight: 600;
  font-size: 0.95rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  display: block;
}
.tp-top-right { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }

.tp-timer {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  font-size: 1.15rem;
  padding: 6px 14px;
  border-radius: 10px;
  background: var(--primary-light);
  color: var(--primary);
  flex-shrink: 0;
}
.tp-timer.warn {
  background: #fdecee;
  color: var(--q-not-answered);
  animation: tpFlash 1.4s ease-in-out infinite;
}
@keyframes tpFlash { 0%, 100% { opacity: 1; } 50% { opacity: 0.55; } }

.tp-submit-top { padding: 9px 20px; font-size: 0.88rem; }
.tp-palette-toggle {
  display: none;
  background: none;
  border: 1px solid var(--border);
  border-radius: 9px;
  padding: 8px 12px;
  font-size: 0.84rem;
  font-weight: 600;
}

/* ---- section tabs ---- */
.tp-sections {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
  padding: 8px 18px;
  background: #fff;
  border-bottom: 1px solid var(--border);
}
.tp-sections::-webkit-scrollbar { display: none; }
.tp-section {
  flex: 0 0 auto;
  background: none;
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 7px 16px;
  font-size: 0.86rem;
  font-weight: 500;
  color: var(--muted);
  white-space: nowrap;
}
.tp-section small { opacity: 0.7; font-size: 0.76rem; }
.tp-section.active {
  background: var(--primary);
  border-color: var(--primary);
  color: #fff;
}

/* ---- main ---- */
.tp-main {
  display: grid;
  grid-template-columns: 1fr 300px;
  min-height: 0;
}

.tp-question-pane {
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 22px 26px 34px;
  background: #fff;
}

.tp-passage {
  background: var(--bg-soft);
  border-left: 3px solid var(--primary);
  border-radius: 0 12px 12px 0;
  padding: 14px 18px;
  margin-bottom: 18px;
  font-size: 0.93rem;
  line-height: 1.7;
  max-height: 38vh;
  overflow-y: auto;
}

.tp-qhead {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 10px;
}
.tp-qnum { font-weight: 700; font-size: 1rem; }
.tp-qmarks {
  font-size: 0.78rem;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  background: var(--bg-soft);
  padding: 3px 9px;
  border-radius: 999px;
}
.tp-qbody { font-size: 1rem; line-height: 1.7; }
.tp-qbody p { margin-bottom: 10px; }
.tp-qimg, .tp-optimg { max-width: 100%; height: auto; border-radius: 10px; margin-top: 10px; }

.tp-img-retry {
  display: block;
  width: 100%;
  min-height: 150px;
  border: 1px dashed var(--border);
  border-radius: 12px;
  background: var(--bg-soft);
  color: var(--muted);
  font-size: 0.88rem;
  margin-top: 10px;
}

/* ---- options ---- */
.tp-options { display: grid; gap: 10px; margin-top: 20px; }
.tp-option {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  text-align: left;
  width: 100%;
  background: #fff;
  border: 1.5px solid var(--border);
  border-radius: 12px;
  padding: 13px 15px;
  font-size: 0.95rem;
  line-height: 1.6;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.tp-option:hover { border-color: #b9c4da; }
.tp-option.chosen {
  border-color: var(--primary);
  background: var(--primary-light);
}
.tp-optkey {
  flex-shrink: 0;
  width: 26px; height: 26px;
  border-radius: 50%;
  border: 1.5px solid var(--border);
  display: grid;
  place-items: center;
  font-size: 0.8rem;
  font-weight: 700;
  color: var(--muted);
  background: #fff;
}
.tp-option.chosen .tp-optkey {
  background: var(--primary);
  border-color: var(--primary);
  color: #fff;
}
.tp-opttext { min-width: 0; }

/* ---- numerical ---- */
.tp-numeric { margin-top: 22px; max-width: 320px; }
.tp-numeric-display {
  border: 1.5px solid var(--primary);
  border-radius: 12px;
  padding: 14px 16px;
  font-size: 1.5rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  text-align: right;
  background: #fff;
  min-height: 58px;
}
.tp-keypad {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
  margin-top: 12px;
}
.tp-key {
  padding: 15px 0;
  font-size: 1.1rem;
  font-weight: 600;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 11px;
}
.tp-key:active { background: var(--primary-light); border-color: var(--primary); }
.tp-key.wide { grid-column: span 3; font-size: 0.9rem; }

/* ---- palette ---- */
.tp-palette {
  border-left: 1px solid var(--border);
  background: #fff;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 16px;
}
.tp-legend {
  display: grid;
  gap: 6px;
  font-size: 0.76rem;
  color: var(--muted);
  padding-bottom: 14px;
  margin-bottom: 14px;
  border-bottom: 1px solid var(--border);
}
.tp-legend span { display: flex; align-items: center; gap: 8px; }
.pal {
  width: 14px; height: 14px;
  border-radius: 4px;
  flex-shrink: 0;
  display: inline-block;
}
.pal.answered { background: var(--q-answered); }
.pal.not_answered { background: var(--q-not-answered); }
.pal.not_visited { background: var(--q-not-visited); }
.pal.marked { background: var(--q-marked); }
.pal.answered_marked { background: var(--q-answered-marked); }

.tp-pal-section { margin-bottom: 16px; }
.tp-pal-section h4 {
  font-size: 0.74rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted);
  margin-bottom: 8px;
}
.tp-pal-row { display: flex; flex-wrap: wrap; gap: 6px; }
.tp-pal {
  width: 38px; height: 38px;
  border-radius: 8px;
  border: none;
  font-size: 0.8rem;
  font-weight: 700;
  color: #fff;
  background: var(--q-not-visited);
}
.tp-pal.answered { background: var(--q-answered); }
.tp-pal.not_answered { background: var(--q-not-answered); }
.tp-pal.not_visited { background: var(--q-not-visited); color: var(--text); }
.tp-pal.marked { background: var(--q-marked); }
.tp-pal.answered_marked { background: var(--q-answered-marked); }
.tp-pal.current { outline: 3px solid var(--q-current); outline-offset: 2px; }

/* ---- action bar ---- */
.tp-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  padding: 12px 18px;
  background: #fff;
  border-top: 1px solid var(--border);
  padding-bottom: calc(12px + env(safe-area-inset-bottom));
}
.tp-btn {
  border: 1px solid var(--border);
  background: #fff;
  border-radius: 10px;
  padding: 11px 18px;
  font-size: 0.88rem;
  font-weight: 600;
}
.tp-btn-ghost { color: var(--muted); }
.tp-btn-report { color: var(--accent-deep); border-color: #f6d9bd; }
.tp-btn-mark { color: var(--q-marked); border-color: #d9cdf7; }
.tp-btn-save { background: var(--primary); border-color: var(--primary); color: #fff; margin-left: auto; }

.tp-saving {
  position: fixed;
  bottom: 84px;
  left: 50%;
  transform: translateX(-50%);
  background: var(--dark);
  color: #fff;
  font-size: 0.76rem;
  padding: 5px 14px;
  border-radius: 999px;
  z-index: 40;
}

/* ---- modals ---- */
.tp-modal-wrap {
  position: fixed;
  inset: 0;
  background: rgba(20, 25, 43, 0.55);
  display: grid;
  place-items: center;
  z-index: 200;
  padding: 22px;
}
.tp-modal {
  background: #fff;
  border-radius: 18px;
  padding: 26px;
  width: min(440px, 100%);
  text-align: center;
}
.tp-modal h2 {
  font-family: "Poppins", "Noto Sans Devanagari", "Segoe UI", system-ui, sans-serif;
  font-weight: 700;
  font-size: 1.7rem;
  margin-bottom: 16px;
}
.tp-modal-plain { display: grid; justify-items: center; gap: 14px; }
.tp-confirm-grid { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }
.tp-confirm-grid > div {
  background: var(--bg-soft);
  border-radius: 12px;
  padding: 12px 18px;
  min-width: 92px;
}
.tp-confirm-grid span { display: block; font-size: 1.3rem; font-weight: 700; }
.tp-confirm-grid small { color: var(--muted); font-size: 0.74rem; }
.tp-confirm-warn { color: var(--muted); font-size: 0.85rem; margin: 16px 0 20px; }
.tp-modal-actions { display: flex; gap: 10px; justify-content: center; }
.tp-report-modal { text-align: left; }
.tp-report-modal h2 { text-align: left; margin-bottom: 6px; }
.tp-report-question { color: var(--muted); font-size: 0.86rem; margin: 0 0 14px; }
.tp-report-modal textarea {
  display: block;
  width: 100%;
  resize: vertical;
  min-height: 104px;
  padding: 11px 12px;
  border: 1px solid var(--border);
  border-radius: 10px;
  font: inherit;
  color: var(--text);
}
.tp-report-modal textarea:focus { outline: 2px solid #c9dcfb; border-color: var(--primary); }
.tp-report-error { margin: 8px 0 0; color: var(--q-not-answered); font-size: 0.82rem; }
.tp-report-modal .tp-modal-actions { justify-content: flex-end; margin-top: 16px; }

/* ---------------------------------------------------------
   RESULT
   --------------------------------------------------------- */
.rs-score {
  display: flex;
  gap: 26px;
  flex-wrap: wrap;
  align-items: center;
  background: var(--bg-soft);
  border-radius: 18px;
  padding: 26px 28px;
  margin: 22px 0 34px;
}
.rs-score-main { flex: 0 0 auto; }
.rs-score-num { font-size: 3.2rem; font-weight: 700; color: var(--primary); line-height: 1; }
.rs-score-max { font-size: 1.2rem; color: var(--muted); margin-left: 4px; }
.rs-score-main small { display: block; color: var(--muted); font-size: 0.8rem; margin-top: 4px; }
.rs-score-side { display: flex; gap: 12px; flex-wrap: wrap; flex: 1 1 260px; }
.rs-score-side > div {
  background: #fff;
  border-radius: 12px;
  padding: 12px 18px;
  min-width: 88px;
}
.rs-score-side span { display: block; font-size: 1.3rem; font-weight: 700; }
.rs-score-side small { color: var(--muted); font-size: 0.74rem; }

.rs-filters { display: flex; gap: 8px; flex-wrap: wrap; margin: 16px 0 20px; }
.rs-filter {
  border: 1px solid var(--border);
  background: #fff;
  border-radius: 999px;
  padding: 7px 16px;
  font-size: 0.84rem;
  font-weight: 500;
  color: var(--muted);
}
.rs-filter.active { background: var(--dark); border-color: var(--dark); color: #fff; }

.rs-q {
  border: 1px solid var(--border);
  border-left: 3px solid var(--q-not-visited);
  border-radius: 0 14px 14px 0;
  padding: 18px 20px;
  margin-bottom: 14px;
  background: #fff;
}
.rs-q.correct { border-left-color: var(--q-answered); }
.rs-q.wrong { border-left-color: var(--q-not-answered); }
.rs-q.voided { border-left-color: var(--q-marked); }

.rs-q-head { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 10px; }
.rs-q-num { font-weight: 700; font-size: 0.88rem; }
.rs-q-marks { margin-left: auto; font-weight: 700; font-variant-numeric: tabular-nums; }
.rs-tag { font-size: 0.72rem; font-weight: 700; padding: 3px 10px; border-radius: 999px; text-transform: uppercase; letter-spacing: 0.04em; }
.rs-tag.correct { background: #e4f5ec; color: var(--q-answered); }
.rs-tag.wrong { background: #fdecee; color: var(--q-not-answered); }
.rs-tag.skipped { background: var(--bg-soft); color: var(--muted); }
.rs-tag.voided { background: #f1ecfd; color: var(--q-marked); }

.rs-q-body { font-size: 0.95rem; line-height: 1.7; }
.rs-q-body img { max-width: 100%; height: auto; border-radius: 10px; margin-top: 10px; }

.rs-opts { margin-top: 12px; display: grid; gap: 7px; list-style: none; }
.rs-opts li {
  padding: 9px 13px;
  border: 1px solid var(--border);
  border-radius: 10px;
  font-size: 0.9rem;
  display: flex;
  gap: 8px;
  align-items: baseline;
  flex-wrap: wrap;
}
.rs-opts li.correct { border-color: var(--q-answered); background: #f2fbf6; }
.rs-opts li.yours { border-color: var(--q-not-answered); background: #fef5f6; }
.rs-opts li.correct.yours { border-color: var(--q-answered); background: #f2fbf6; }
.rs-opts em {
  margin-left: auto;
  font-style: normal;
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
}
.rs-opts li.correct em { color: var(--q-answered); }

.rs-numeric { display: flex; gap: 22px; flex-wrap: wrap; margin-top: 12px; font-size: 0.9rem; }

.rs-solution { margin-top: 12px; border-top: 1px solid var(--border); padding-top: 10px; }
.rs-solution summary { cursor: pointer; font-weight: 600; font-size: 0.86rem; color: var(--primary); }
.rs-solution div { margin-top: 10px; font-size: 0.92rem; line-height: 1.7; color: var(--text); }

.rs-cta { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 30px; }

.table-scroll { overflow-x: auto; }

/* ---------------------------------------------------------
   RESPONSIVE
   --------------------------------------------------------- */
@media (max-width: 900px) {
  .tp-main { grid-template-columns: 1fr; }
  .tp-palette-toggle { display: block; }

  /* palette becomes a sheet so the question keeps the full screen */
  .tp-palette {
    position: fixed;
    inset: auto 0 0 0;
    max-height: 62dvh;
    border-left: none;
    border-top: 1px solid var(--border);
    border-radius: 18px 18px 0 0;
    box-shadow: var(--shadow-lg);
    transform: translateY(100%);
    transition: transform 0.25s ease;
    z-index: 60;
  }
  .tp-palette.open { transform: translateY(0); }

  .tp-question-pane { padding: 18px 18px 30px; }
  .tp-top { padding: 8px 14px; gap: 10px; }
  .tp-timer { font-size: 1rem; padding: 5px 11px; }
  .tp-submit-top { padding: 8px 14px; }
  .tp-actions { padding-left: 12px; padding-right: 12px; gap: 7px; }
  .tp-btn { padding: 11px 12px; font-size: 0.8rem; flex: 1 1 auto; }
  .tp-btn-save { flex: 1 1 100%; order: -1; margin-left: 0; }
}

@media (max-width: 560px) {
  .tp-test-name { font-size: 0.85rem; }
  .tp-pal { width: 34px; height: 34px; }
  .rs-score-num { font-size: 2.4rem; }
  .mt-paper { align-items: flex-start; }
  .mt-paper .btn { width: 100%; text-align: center; }
}


/* =========================================================
   OWNER APPROVAL CONSOLE (.ad-*)
   ========================================================= */
.ad-who { font-size: 0.82rem; color: var(--muted); }

.ad-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  flex-wrap: wrap;
  margin: 20px 0 22px;
}
.ad-bar .rs-filters { margin: 0; }
.ad-bar .rs-filter span {
  display: inline-block;
  min-width: 18px;
  margin-left: 5px;
  padding: 0 5px;
  border-radius: 999px;
  background: var(--border);
  font-size: 0.72rem;
  font-weight: 700;
}
.ad-bar .rs-filter.active span { background: rgba(255, 255, 255, 0.25); }
.ad-refresh { border: 1px solid var(--border); padding: 9px 20px; font-size: 0.86rem; }

.ad-card {
  display: grid;
  grid-template-columns: 108px 1fr auto;
  gap: 18px;
  align-items: center;
  background: #fff;
  border: 1px solid var(--border);
  border-left: 3px solid var(--q-not-visited);
  border-radius: 0 14px 14px 0;
  padding: 16px 18px;
  margin-bottom: 12px;
  transition: opacity 0.2s ease;
}
.ad-card.pending { border-left-color: var(--accent); }
.ad-card.approved { border-left-color: var(--q-answered); }
.ad-card.rejected { border-left-color: var(--q-not-answered); }
.ad-card.busy { opacity: 0.5; pointer-events: none; }

.ad-shotcell { width: 108px; }
.ad-thumb {
  width: 108px;
  height: 108px;
  object-fit: cover;
  border-radius: 10px;
  border: 1px solid var(--border);
  cursor: zoom-in;
  background: var(--bg-soft);
}
.ad-noshot {
  width: 108px; height: 108px;
  border: 1px dashed var(--border);
  border-radius: 10px;
  display: grid;
  place-items: center;
  font-size: 0.72rem;
  color: var(--muted);
  text-align: center;
  padding: 6px;
}

.ad-info { min-width: 0; }
.ad-line1 { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.ad-line1 strong { font-size: 1rem; }
.ad-status {
  font-size: 0.68rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 2px 9px;
  border-radius: 999px;
}
.ad-status.pending { background: #fff2e4; color: var(--accent-deep); }
.ad-status.approved { background: #e4f5ec; color: var(--q-answered); }
.ad-status.rejected { background: #fdecee; color: var(--q-not-answered); }

.ad-email { font-size: 0.85rem; color: var(--muted); word-break: break-all; }
.ad-course { font-size: 0.9rem; margin-top: 4px; }
.ad-tag {
  font-size: 0.66rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  background: var(--primary-light);
  color: var(--primary);
  padding: 2px 8px;
  border-radius: 999px;
  vertical-align: middle;
}
.ad-meta { font-size: 0.8rem; color: var(--muted); margin-top: 3px; }
.ad-grant { font-size: 0.8rem; font-weight: 600; margin-top: 6px; }
.ad-grant.ok { color: var(--q-answered); }
.ad-grant.bad { color: var(--accent-deep); }

.ad-actions { display: flex; flex-direction: column; gap: 8px; }
.ad-actions button {
  border: none;
  border-radius: 10px;
  padding: 11px 24px;
  font-size: 0.86rem;
  font-weight: 600;
  white-space: nowrap;
}
.ad-yes { background: var(--q-answered); color: #fff; }
.ad-no { background: #fff; color: var(--q-not-answered); border: 1px solid #f3c6cc !important; }
.ad-undo { background: #fff; color: var(--muted); border: 1px solid var(--border) !important; }

.ad-shot-inner {
  display: grid;
  justify-items: center;
  gap: 14px;
  max-width: min(760px, 92vw);
}
.ad-shot-inner img {
  max-width: 100%;
  max-height: 76vh;
  border-radius: 12px;
  background: #fff;
}

@media (max-width: 700px) {
  .ad-card { grid-template-columns: 76px 1fr; }
  .ad-shotcell, .ad-thumb, .ad-noshot { width: 76px; }
  .ad-thumb, .ad-noshot { height: 76px; }
  .ad-actions { grid-column: 1 / -1; flex-direction: row; }
  .ad-actions button { flex: 1; }
}


/* staff-only shortcut on the profile page */
.profile-staff-link {
  color: var(--primary) !important;
  font-weight: 600;
}
.profile-staff-link::before { content: "\2699\FE0F  "; }

/* =========================================================
   PROCTORING
   ========================================================= */

/* Nothing inside the exam may be selected or copied. Kept off the inputs the
   student legitimately uses so focus and taps still behave. */
.tp-shell,
.tp-qbody,
.tp-passage,
.tp-options,
.tp-option,
.tp-numeric-display {
  -webkit-user-select: none;
  -ms-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}

/* the "you left the test" overlay â€” deliberately alarming */
.tp-proctor { background: rgba(140, 12, 26, 0.82); backdrop-filter: blur(3px); }

.tp-modal-warn { border-top: 5px solid var(--q-not-answered); }

.tp-away-ring {
  width: 78px;
  height: 78px;
  margin: 0 auto 16px;
  border-radius: 50%;
  border: 4px solid var(--q-not-answered);
  color: var(--q-not-answered);
  display: grid;
  place-items: center;
  font-size: 2.1rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  animation: tpPulseRing 1s ease-in-out infinite;
}
@keyframes tpPulseRing {
  0%, 100% { transform: scale(1); opacity: 1; }
  50% { transform: scale(1.06); opacity: 0.75; }
}

.tp-away-count {
  margin-top: 12px;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--q-not-answered);
  font-variant-numeric: tabular-nums;
}

.tp-modal-warn p { color: var(--muted); font-size: 0.92rem; }
.tp-modal-warn .btn { margin-top: 4px; }

/* the flash toast reuses .tp-saving, but proctor messages are warnings */
.tp-saving { max-width: min(90vw, 420px); text-align: center; }


/* =========================================================
   RANK LIST + admin re-attempt grant
   ========================================================= */
.rs-rank-head {
  display: flex;
  align-items: center;
  gap: 20px;
  flex-wrap: wrap;
  margin: 16px 0 14px;
}
.rs-myrank {
  background: var(--primary-light);
  border-radius: 14px;
  padding: 12px 22px;
  text-align: center;
  flex-shrink: 0;
}
.rs-myrank span { display: block; font-size: 2rem; font-weight: 700; color: var(--primary); line-height: 1.1; }
.rs-myrank small { color: var(--muted); font-size: 0.76rem; }
.rs-myrank b { font-weight: 600; }

.rs-rank-note { font-size: 0.85rem; color: var(--muted); }
.rs-rank-note.live {
  color: var(--accent-deep);
  font-weight: 600;
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.rs-rank-note.live::before {
  content: "";
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--accent);
  animation: mtPulse 1.6s ease-in-out infinite;
}

.rs-rank-table { width: 100%; }
.rs-rank-table td, .rs-rank-table th { white-space: nowrap; }
.rs-rank-table tr.you { background: var(--primary-light); }
.rs-rank-table tr.you td { font-weight: 600; }
.rs-you-tag {
  font-size: 0.66rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  background: var(--primary);
  color: #fff;
  padding: 1px 7px;
  border-radius: 999px;
  vertical-align: middle;
}

/* ---- admin: grant a re-attempt ---- */
.ad-grant-box {
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 18px 20px;
  margin: 22px 0 8px;
  background: var(--bg-soft);
}
.ad-grant-box h3 { font-size: 1rem; font-weight: 600; }
.ad-grant-box p { font-size: 0.84rem; color: var(--muted); margin: 4px 0 12px; }
.ad-grant-row { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.ad-grant-row select,
.ad-grant-row input {
  flex: 1 1 190px;
  min-width: 0;
  padding: 10px 13px;
  border: 1px solid var(--border);
  border-radius: 10px;
  font-family: inherit;
  font-size: 0.9rem;
  background: #fff;
}
.ad-grant-row button { flex: 0 0 auto; }
.ad-grant-msg { font-size: 0.85rem; margin-top: 10px; }
.ad-grant-msg.ok { color: var(--q-answered); font-weight: 600; }
.ad-grant-msg.bad { color: var(--q-not-answered); font-weight: 600; }

@media (max-width: 560px) {
  .rs-myrank { width: 100%; }
}


/* ranked-test badges on the dashboard */
.mt-ranked {
  font-size: 0.66rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  background: #f1ecfd;
  color: var(--q-marked);
  padding: 2px 9px;
  border-radius: 999px;
  vertical-align: middle;
  white-space: nowrap;
}
.mt-closed { border: 1px solid var(--border); color: var(--muted); pointer-events: none; opacity: 0.75; }

/* =========================================================
   MASTER CONSOLE â€” tiles, tabs, staff, reports, flags
   ========================================================= */
.ad-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 12px;
  margin: 22px 0 18px;
}
.ad-tiles.small { margin: 4px 0 18px; }
.ad-tile {
  background: var(--bg-soft);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 14px 18px;
}
.ad-tile span { display: block; font-size: 1.7rem; font-weight: 700; line-height: 1.1; }
.ad-tile small { color: var(--muted); font-size: 0.76rem; }
.ad-tile.urgent { background: #fff2e4; border-color: #f6d9bd; }
.ad-tile.urgent span { color: var(--accent-deep); }

.ad-tabs {
  display: flex;
  gap: 6px;
  overflow-x: auto;
  scrollbar-width: none;
  border-bottom: 2px solid var(--border);
  margin-bottom: 22px;
}
.ad-tabs::-webkit-scrollbar { display: none; }
.ad-tab {
  flex: 0 0 auto;
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  margin-bottom: -2px;
  padding: 11px 16px;
  font-size: 0.92rem;
  font-weight: 500;
  color: var(--muted);
  white-space: nowrap;
}
.ad-tab.active { color: var(--primary); border-bottom-color: var(--primary); font-weight: 600; }
.ad-tab span {
  display: inline-block;
  min-width: 18px;
  margin-left: 5px;
  padding: 0 6px;
  border-radius: 999px;
  background: var(--border);
  font-size: 0.7rem;
  font-weight: 700;
}
.ad-tab.active span { background: var(--primary); color: #fff; }

.ad-panel { display: none; }
.ad-panel.active { display: block; }

.ad-select {
  flex: 1 1 260px;
  padding: 10px 13px;
  border: 1px solid var(--border);
  border-radius: 10px;
  font-family: inherit;
  font-size: 0.9rem;
  background: #fff;
}

.ad-subhead {
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted);
  margin: 26px 0 10px;
}

/* ---- staff list ---- */
.ad-staff { display: grid; gap: 8px; }
.ad-staff-row {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 13px 16px;
}
.ad-staff-row > div { flex: 1 1 220px; min-width: 0; }
.ad-staff-row strong { display: block; font-size: 0.95rem; }
.ad-staff-row .ad-meta { display: block; }
.ad-staff-row.owner { background: var(--primary-light); border-color: #c9dcfb; }
.ad-staff-row button {
  border: 1px solid var(--border);
  border-radius: 9px;
  padding: 8px 16px;
  font-size: 0.82rem;
  font-weight: 600;
}
.ad-status.pending { background: #fff2e4; color: var(--accent-deep); }

/* ---- report tables ---- */
.ad-report { width: 100%; font-size: 0.88rem; }
.ad-report th, .ad-report td { white-space: nowrap; }
.ad-report .ad-email-cell { display: block; margin-top: 3px; }
.ad-question-reports .ad-question-reason { min-width: 280px; max-width: 520px; white-space: normal; }
.ad-report tr.flagged { background: #fdf3f4; }
.ad-email-cell { color: var(--muted); font-size: 0.82rem; }
.ad-flag-tag {
  font-size: 0.66rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  background: #fdecee;
  color: var(--q-not-answered);
  padding: 2px 8px;
  border-radius: 999px;
}

/* ---- the honesty notice above the flags table ---- */
.ad-warnbox {
  background: #fff6ed;
  border: 1px solid #f6d9bd;
  border-left: 3px solid var(--accent);
  border-radius: 0 12px 12px 0;
  padding: 14px 18px;
  font-size: 0.88rem;
  line-height: 1.65;
  color: var(--text);
  margin-bottom: 20px;
}
.ad-warnbox strong { display: block; margin-bottom: 3px; color: var(--accent-deep); }

@media (max-width: 700px) {
  .ad-tile span { font-size: 1.4rem; }
  .ad-staff-row button { width: 100%; }
}


/* owner-only console shortcut in the header — visually distinct from every
   student-facing control so it is obvious this account is not a normal one */
.btn-console {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  background: var(--primary);
  color: #fff;
  font-size: 0.82rem;
  font-weight: 600;
  padding: 9px 16px;
  border-radius: 9px;
  white-space: nowrap;
  transition: background 0.2s ease;
}
.btn-console::before { content: "\2699\FE0F"; font-size: 0.9rem; }
.btn-console:hover { background: var(--primary-dark); }

@media (max-width: 560px) {
  .btn-console { padding: 8px 11px; font-size: 0.76rem; }
  .btn-console::before { margin: 0; }
}

/* the "needs you now" strip — empty on a good day */
.ad-alert {
  display: block;
  border-radius: 0 12px 12px 0;
  padding: 13px 18px;
  margin-bottom: 10px;
  font-size: 0.88rem;
  line-height: 1.6;
}
.ad-alert strong { display: block; margin-bottom: 2px; }
.ad-alert span { color: var(--muted); font-size: 0.84rem; word-break: break-word; }
.ad-alert.bad {
  background: #fdecee;
  border: 1px solid #f3c6cc;
  border-left: 3px solid var(--q-not-answered);
}
.ad-alert.bad strong { color: #a3172a; }
.ad-alert.warn {
  background: #fff6ed;
  border: 1px solid #f6d9bd;
  border-left: 3px solid var(--accent);
}
.ad-alert.warn strong { color: var(--accent-deep); }

.ad-undo-note {
  display: block;
  font-size: 0.68rem;
  color: var(--muted);
  text-align: center;
  margin-top: 4px;
  max-width: 130px;
  line-height: 1.35;
}

/* =========================================================
   SIGN-IN â€” split layout with a proof panel
   The page has exactly one control (Google is the only provider), so the
   other half is given a job rather than left empty. The stats are the same
   four already on the homepage â€” nothing new to write or keep in sync.
   ========================================================= */
.auth-split {
  display: grid;
  grid-template-columns: 1.05fr 0.95fr;
  min-height: calc(100dvh - 64px);
}

/* ---------- left: the proof panel ---------- */
.auth-panel {
  position: relative;
  overflow: hidden;
  background: linear-gradient(150deg, #12224d 0%, var(--primary) 100%);
  color: #fff;
  padding: 56px 56px 52px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
/* two soft discs â€” cheaper than an image and never fail to load */
.auth-panel::before,
.auth-panel::after {
  content: "";
  position: absolute;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.06);
  pointer-events: none;
}
.auth-panel::before { right: 44px; top: -70px; width: 190px; height: 190px; }
.auth-panel::after { right: -100px; bottom: -100px; width: 330px; height: 330px; }

.auth-panel > * { position: relative; }

.auth-panel-eyebrow {
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: #a9c1ec;
  margin-bottom: 18px;
}
.auth-panel-head {
  font-family: "Poppins", "Noto Sans Devanagari", "Segoe UI", system-ui, sans-serif;
  font-weight: 800;
  font-size: clamp(2rem, 3.4vw, 2.7rem);
  line-height: 1.14;
  letter-spacing: -0.01em;
  margin-bottom: 10px;
  max-width: 17ch;
}
.auth-panel-sub {
  color: #c3d5f7;
  font-size: 0.95rem;
  max-width: 36ch;
  line-height: 1.7;
}

.auth-stats {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 22px 16px;
  margin-top: 40px;
}
.auth-stat b { display: block; font-size: 1.5rem; font-weight: 700; line-height: 1.1; }
.auth-stat span { font-size: 0.78rem; color: #a9c1ec; }

/* ---------- right: the sign-in ---------- */
.auth-side {
  display: grid;
  place-items: center;
  padding: 52px 40px;
  background: var(--bg);
}
.auth-side-inner { width: min(400px, 100%); }

.auth-title {
  font-family: "Poppins", "Noto Sans Devanagari", "Segoe UI", system-ui, sans-serif;
  font-weight: 700;
  font-size: 2rem;
  line-height: 1.15;
  letter-spacing: -0.01em;
  margin-bottom: 4px;
}

/* the one control on the page deserves a little more presence than the
   compact version used inside the checkout card */
.auth-side .btn-google {
  gap: 12px;
  border-radius: 12px;
  padding: 14px 20px;
  font-size: 0.98rem;
  transition: border-color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease;
}
.auth-side .btn-google:hover { border-color: #c3cddf; transform: translateY(-1px); }
.auth-side .btn-google svg { width: 22px; height: 22px; }

.auth-fineprint a { color: var(--primary); text-decoration: underline; text-underline-offset: 2px; }

/* ---------- employee entrance ---------- */
.auth-emp-row {
  margin-top: 28px;
  padding-top: 20px;
  border-top: 1px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}
.auth-emp-row small { color: var(--muted); font-size: 0.8rem; }
.auth-emp {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--muted);
  border: 1px solid var(--border);
  padding: 9px 16px;
  border-radius: 9px;
  transition: border-color 0.2s ease, color 0.2s ease, background 0.2s ease;
}
.auth-emp::before { content: "\2699\FE0F"; }
.auth-emp:hover { border-color: var(--primary); color: var(--primary); background: var(--primary-light); }

@media (max-width: 900px) {
  .auth-split { grid-template-columns: 1fr; min-height: 0; }
  /* The form comes FIRST on a phone. Someone who came here to sign in should
     not have to scroll past a marketing panel to find the button. */
  .auth-side { order: -1; padding: 40px 24px 34px; }
  .auth-panel { padding: 40px 26px 44px; }
  .auth-panel-head { font-size: 1.7rem; max-width: none; }
  .auth-panel::before { display: none; }
  .auth-stats { margin-top: 28px; gap: 18px 14px; }
}

@media (max-width: 420px) {
  .auth-stats { grid-template-columns: 1fr; }
  .auth-emp-row { justify-content: flex-start; }
}

/* ---------- employee entrance ---------- */
.emp-panel { background: linear-gradient(150deg, #0c1024 0%, #1c2a52 100%); }
.emp-list { margin-top: 30px; display: grid; gap: 11px; position: relative; }
.emp-list li {
  position: relative;
  padding-left: 22px;
  font-size: 0.88rem;
  color: #c3d5f7;
  line-height: 1.6;
}
.emp-list li::before {
  content: "";
  position: absolute;
  left: 0; top: 0.58em;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: #7fa6f0;
}
.emp-badge {
  width: 52px; height: 52px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-size: 1.4rem;
  margin-bottom: 14px;
}
.emp-badge.ok { background: #e4f5ec; color: #14804a; }
.emp-badge.wait { background: #fff2e4; }
.emp-soon {
  background: var(--bg-soft);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 14px 16px;
  font-size: 0.86rem;
  color: var(--muted);
  line-height: 1.65;
  margin: 18px 0 20px;
}
.emp-soon b { color: var(--text); }
.emp-recheck {
  width: 100%;
  background: var(--primary);
  color: #fff;
  border: none;
  border-radius: 10px;
  padding: 12px 18px;
  font-size: 0.9rem;
  font-weight: 600;
  margin-bottom: 10px;
}
.emp-recheck:disabled { opacity: 0.6; }


/* =========================================================
   TEACHING PANEL (employee.html)
   Reuses .tp-modal / .tp-btn from the test player deliberately, and overrides
   the two things that were tuned for a narrow confirmation dialog.
   ========================================================= */
.tp-panel { padding: 34px 0 70px; }

.tp-panel-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 18px;
  flex-wrap: wrap;
  margin-bottom: 24px;
}
.tp-panel-actions { display: flex; align-items: center; gap: 12px; }
.btn-signout.tp-out { width: auto; margin: 0; padding: 9px 18px; font-size: .84rem; }

.tp-back {
  background: none;
  border: none;
  color: var(--primary);
  font-size: .88rem;
  font-weight: 600;
  padding: 0 0 16px;
}

/* ---- cards ---- */
.tp-card {
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 24px 26px;
  margin-bottom: 18px;
}
.tp-card-head {
  font-size: 1rem;
  font-weight: 700;
  margin-bottom: 18px;
  display: flex;
  align-items: center;
  gap: 10px;
}
.tp-count {
  font-size: .74rem;
  font-weight: 700;
  background: var(--primary-light);
  color: var(--primary);
  padding: 2px 10px;
  border-radius: 999px;
}
.tp-card-foot {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  margin-top: 20px;
  padding-top: 18px;
  border-top: 1px solid var(--border);
}

/* ---- forms ---- */
.tp-form { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.tp-field { display: grid; gap: 6px; min-width: 0; }
.tp-field.tp-wide, .tp-form.tp-wide { grid-column: 1 / -1; }
.tp-field > span { font-size: .82rem; font-weight: 600; }
.tp-hint { display: block; font-weight: 400; color: var(--muted); font-size: .76rem; margin-top: 2px; }

.tp-field input[type="text"],
.tp-field input[type="number"],
.tp-field input[type="datetime-local"],
.tp-field select,
.tp-field textarea {
  width: 100%;
  padding: 11px 13px;
  border: 1px solid var(--border);
  border-radius: 10px;
  font-family: inherit;
  font-size: .92rem;
  color: var(--text);
  background: #fff;
}
.tp-field textarea { resize: vertical; line-height: 1.6; }
.tp-field input:focus, .tp-field select:focus, .tp-field textarea:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--primary-light);
}

.tp-radio-row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.tp-radio-row.tp-radio-sm { grid-template-columns: repeat(3, 1fr); }
.tp-radio {
  display: block;
  border: 1.5px solid var(--border);
  border-radius: 12px;
  padding: 13px 15px;
  cursor: pointer;
  transition: border-color .18s ease, background .18s ease;
}
.tp-radio input { margin-right: 8px; accent-color: var(--primary); }
.tp-radio b { font-size: .9rem; font-weight: 600; }
.tp-radio small { display: block; color: var(--muted); font-size: .76rem; margin-top: 3px; line-height: 1.5; }
.tp-radio:has(input:checked) { border-color: var(--primary); background: var(--primary-light); }

.tp-check { display: flex; align-items: center; gap: 9px; font-size: .88rem; }
.tp-check input { accent-color: var(--primary); width: 17px; height: 17px; }

.tp-ranked-only {
  grid-column: 1 / -1;
  border-left: 3px solid var(--q-marked);
  background: #faf8ff;
  border-radius: 0 12px 12px 0;
  padding: 16px 18px;
}

/* ---- sections editor ---- */
.tp-presets { font-size: .8rem; color: var(--muted); margin-bottom: 10px; }
.tp-presets button {
  background: var(--bg-soft);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 5px 13px;
  font-size: .78rem;
  font-weight: 600;
  margin-left: 6px;
}
.tp-presets button:hover { border-color: var(--primary); color: var(--primary); }

.tp-sec {
  display: grid;
  grid-template-columns: 1.3fr 1fr 78px 78px 34px;
  gap: 8px;
  align-items: center;
  margin-bottom: 8px;
}
.tp-sec input {
  width: 100%;
  padding: 9px 11px;
  border: 1px solid var(--border);
  border-radius: 9px;
  font-family: inherit;
  font-size: .86rem;
}
.tp-sec label { display: flex; align-items: center; gap: 4px; font-size: .82rem; color: var(--muted); font-weight: 600; }
.tp-sec label input { padding: 9px 6px; text-align: center; }
.s-del {
  background: none;
  border: 1px solid var(--border);
  border-radius: 8px;
  height: 36px;
  color: var(--muted);
  font-size: 1.1rem;
  line-height: 1;
}
.s-del:hover { border-color: var(--q-not-answered); color: var(--q-not-answered); }

.tp-addsec {
  background: none;
  border: 1px dashed var(--border);
  border-radius: 10px;
  padding: 10px 18px;
  font-size: .85rem;
  font-weight: 600;
  color: var(--primary);
  margin-top: 8px;
}
.tp-addsec:hover { border-color: var(--primary); background: var(--primary-light); }

/* ---- paper list ---- */
.tp-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  flex-wrap: wrap;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 16px 20px;
  margin-bottom: 10px;
}
.tp-row-main { flex: 1 1 300px; min-width: 0; }
.tp-row h4 { font-size: 1rem; font-weight: 600; display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.tp-row .btn { padding: 9px 22px; font-size: .86rem; }

/* ---- question list ---- */
.tp-q {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 13px 16px;
  margin-bottom: 8px;
}
.tp-q-main { display: flex; gap: 13px; align-items: flex-start; flex: 1 1 auto; min-width: 0; }
.tp-q-seq {
  flex: 0 0 auto;
  background: var(--bg-soft);
  border-radius: 8px;
  padding: 4px 10px;
  font-size: .78rem;
  font-weight: 700;
  color: var(--muted);
}
.tp-q p { font-size: .9rem; line-height: 1.5; }
.tp-q small { color: var(--muted); font-size: .77rem; }
.tp-q-acts { display: flex; gap: 7px; flex: 0 0 auto; }
.tp-q-acts button {
  border: 1px solid var(--border);
  background: #fff;
  border-radius: 8px;
  padding: 7px 14px;
  font-size: .8rem;
  font-weight: 600;
}
.q-del:hover { border-color: var(--q-not-answered); color: var(--q-not-answered); }
.q-edit:hover { border-color: var(--primary); color: var(--primary); }

/* ---- options editor ---- */
.tp-opt { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.tp-opt input[type="radio"], .tp-opt input[type="checkbox"] { accent-color: #14804a; width: 18px; height: 18px; flex: 0 0 auto; }
.tp-opt-key {
  flex: 0 0 auto;
  width: 26px; height: 26px;
  border-radius: 50%;
  border: 1px solid var(--border);
  display: grid;
  place-items: center;
  font-size: .76rem;
  font-weight: 700;
  color: var(--muted);
}
.tp-opt .o-txt {
  flex: 1 1 auto;
  min-width: 0;
  padding: 9px 12px;
  border: 1px solid var(--border);
  border-radius: 9px;
  font-family: inherit;
  font-size: .88rem;
}
.o-del {
  flex: 0 0 auto;
  background: none;
  border: 1px solid var(--border);
  border-radius: 8px;
  width: 32px; height: 32px;
  color: var(--muted);
  font-size: 1.1rem;
  line-height: 1;
}

/* ---- image upload ---- */
.tp-upload input[type="file"] { font-size: .84rem; }
.tp-thumb { display: flex; align-items: center; gap: 12px; margin-top: 10px; }
.tp-thumb img { width: 92px; height: 92px; object-fit: cover; border-radius: 10px; border: 1px solid var(--border); }
.tp-thumb button {
  border: 1px solid var(--border);
  background: #fff;
  border-radius: 8px;
  padding: 7px 14px;
  font-size: .8rem;
  font-weight: 600;
  color: var(--muted);
}

/* ---- messages ---- */
.tp-msg { font-size: .84rem; font-weight: 600; }
.tp-msg.ok { color: var(--q-answered); }
.tp-msg.bad { color: var(--q-not-answered); }
/* "Saved, but here is what is still missing." Not an error — saving an
   incomplete question is deliberately allowed — so it must not read as one. */
.tp-msg.warn { color: var(--accent-deep); }

/* ---- the question modal is a form, not a confirmation dialog ---- */
.tp-qmodal {
  width: min(720px, 100%);
  max-height: 92dvh;
  overflow-y: auto;
  text-align: left;
  padding: 28px 30px;
}
.tp-qmodal h2 { text-align: left; font-size: 1.5rem; margin-bottom: 20px; }
.tp-qmodal .tp-modal-actions { justify-content: flex-end; margin-top: 22px; }

@media (max-width: 760px) {
  .tp-form, .tp-radio-row, .tp-radio-row.tp-radio-sm { grid-template-columns: 1fr; }
  .tp-sec { grid-template-columns: 1fr 1fr; }
  .tp-sec .s-del { grid-column: 1 / -1; }
  .tp-panel-head { align-items: flex-start; }
  .tp-card { padding: 20px 18px; }
}


/* activity feed in the master console */
.ad-feed { display: grid; gap: 8px; }
.ad-feed-row {
  display: flex;
  align-items: flex-start;
  gap: 13px;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 13px 16px;
}
.ad-feed-row > div { flex: 1 1 auto; min-width: 0; }
.ad-feed-ico {
  flex: 0 0 auto;
  width: 32px; height: 32px;
  border-radius: 9px;
  background: var(--bg-soft);
  display: grid;
  place-items: center;
  font-size: .95rem;
}
.ad-feed-row p { font-size: .9rem; line-height: 1.5; }
.ad-feed-row small { color: var(--muted); font-size: .76rem; }
.ad-feed-tag {
  flex: 0 0 auto;
  font-size: .72rem;
  font-weight: 600;
  color: var(--muted);
  background: var(--bg-soft);
  border-radius: 999px;
  padding: 4px 11px;
  max-width: 200px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
@media (max-width: 620px) { .ad-feed-tag { display: none; } }

/* =========================================================
   BATCHES â€” admin side (.ab-*) and student side (.mb-*)
   ========================================================= */

/* ---- admin: one batch ---- */
.ab-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 22px;
  flex-wrap: wrap;
}
.ab-head .tp-card-head { margin-bottom: 2px; }

.ab-code {
  background: var(--primary-light);
  border: 1px solid #c9dcfb;
  border-radius: 12px;
  padding: 12px 18px;
  text-align: center;
  flex: 0 0 auto;
}
.ab-code small {
  display: block;
  font-size: .68rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .09em;
  color: var(--primary);
}
.ab-code b {
  display: block;
  font-size: 1.6rem;
  font-weight: 700;
  letter-spacing: .12em;
  color: var(--dark);
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  margin: 2px 0 3px;
}
.ab-code span { display: block; font-size: .72rem; color: var(--muted); max-width: 22ch; line-height: 1.45; }

.ab-inline-code {
  font-family: ui-monospace, Consolas, monospace;
  font-weight: 700;
  letter-spacing: .06em;
  background: var(--bg-soft);
  border-radius: 5px;
  padding: 1px 6px;
}

/* ---- student: join box ---- */
.mb-joinbox {
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 18px;
  padding: 34px 32px;
  max-width: 540px;
  margin-top: 22px;
}
.mb-joinbox h2 {
  font-family: "Poppins", "Noto Sans Devanagari", "Segoe UI", system-ui, sans-serif;
  font-weight: 700;
  font-size: 1.8rem;
  margin-bottom: 6px;
}
.mb-joinbox p { color: var(--muted); font-size: .92rem; line-height: 1.65; }
.mb-joinbox.pending { text-align: center; }

.mb-joinrow { display: flex; gap: 10px; margin-top: 20px; flex-wrap: wrap; }
.mb-joinrow input {
  flex: 1 1 180px;
  min-width: 0;
  padding: 13px 16px;
  border: 1.5px solid var(--border);
  border-radius: 11px;
  font-family: ui-monospace, Consolas, monospace;
  font-size: 1.15rem;
  font-weight: 700;
  letter-spacing: .18em;
  text-transform: uppercase;
  text-align: center;
}
.mb-joinrow input:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--primary-light);
}
.mb-joinrow .btn { flex: 0 0 auto; }

/* ---- student: the batch card ---- */
.mb-card {
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 18px;
  padding: 26px 28px;
  margin-top: 22px;
}
.mb-card-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 14px;
  flex-wrap: wrap;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--border);
}
.mb-card-head h2 {
  font-family: "Poppins", "Noto Sans Devanagari", "Segoe UI", system-ui, sans-serif;
  font-weight: 700;
  font-size: 1.9rem;
  letter-spacing: -.01em;
}
.mb-tag {
  font-size: .72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .06em;
  background: var(--primary-light);
  color: var(--primary);
  padding: 4px 12px;
  border-radius: 999px;
}

.mb-teachers { margin-top: 20px; }
.mb-teachers h3 {
  font-size: .74rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .09em;
  color: var(--muted);
  margin-bottom: 10px;
}
.mb-teachers ul { display: flex; gap: 10px; flex-wrap: wrap; }
.mb-teachers li {
  background: var(--bg-soft);
  border-radius: 11px;
  padding: 10px 16px;
  font-size: .9rem;
}
.mb-teachers li span { display: block; font-size: .76rem; color: var(--muted); }

.mb-soon {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 12px;
  margin-top: 24px;
  padding-top: 20px;
  border-top: 1px dashed var(--border);
}
.mb-soon > div {
  border: 1px dashed var(--border);
  border-radius: 12px;
  padding: 14px 16px;
}
.mb-soon b { display: block; font-size: .9rem; }
.mb-soon span { font-size: .78rem; color: var(--muted); line-height: 1.5; }

@media (max-width: 620px) {
  .ab-code { width: 100%; }
  .mb-joinbox { padding: 26px 22px; }
}


/* =========================================================
   CLASSROOM â€” timetable, attendance, hours, offline marks
   ========================================================= */

/* ---- timetable ---- */
.tt-day { margin-bottom: 18px; }
.tt-day h4 {
  font-size: .74rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .09em;
  color: var(--muted);
  margin-bottom: 8px;
}
.tt-slot {
  display: flex;
  align-items: center;
  gap: 14px;
  background: #fff;
  border: 1px solid var(--border);
  border-left: 3px solid var(--primary);
  border-radius: 0 11px 11px 0;
  padding: 11px 15px;
  margin-bottom: 7px;
}
.tt-time {
  flex: 0 0 auto;
  font-family: ui-monospace, Consolas, monospace;
  font-size: .84rem;
  font-weight: 600;
  color: var(--muted);
  background: var(--bg-soft);
  border-radius: 7px;
  padding: 3px 9px;
}
.tt-sub { flex: 1 1 auto; font-weight: 600; font-size: .93rem; min-width: 0; }
.tt-teacher { flex: 0 0 auto; font-size: .8rem; color: var(--muted); }
.tt-del {
  flex: 0 0 auto;
  background: none;
  border: 1px solid var(--border);
  border-radius: 7px;
  width: 30px; height: 30px;
  color: var(--muted);
  font-size: 1.05rem;
  line-height: 1;
}
.tt-del:hover { border-color: var(--q-not-answered); color: var(--q-not-answered); }

/* ---- attendance ---- */
.at-period {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  background: #fff;
  border: 1px solid var(--border);
  border-left: 3px solid var(--q-not-answered);
  border-radius: 0 12px 12px 0;
  padding: 15px 18px;
  margin-bottom: 9px;
}
.at-period.done { border-left-color: var(--q-answered); }
.at-period h4 { font-size: .98rem; font-weight: 600; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.at-period small { color: var(--muted); font-size: .8rem; }
.at-period .btn { padding: 9px 20px; font-size: .85rem; }

.at-bulk { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin: 14px 0; }
.at-bulk button {
  border: 1px solid var(--border);
  background: #fff;
  border-radius: 9px;
  padding: 7px 14px;
  font-size: .8rem;
  font-weight: 600;
}
.at-bulk .tp-msg { margin-left: auto; color: var(--muted); }

.at-student {
  display: flex;
  align-items: center;
  gap: 12px;
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 10px 14px;
  margin-bottom: 6px;
  cursor: pointer;
}
.at-student input { width: 19px; height: 19px; accent-color: #14804a; flex: 0 0 auto; }
.at-student span { display: flex; flex-direction: column; min-width: 0; }
.at-student small { color: var(--muted); font-size: .76rem; }
.at-student:has(input:not(:checked)) { background: #fef5f6; border-color: #f3c6cc; }

/* ---- my hours ---- */
.hr-row {
  display: grid;
  grid-template-columns: 1.2fr 1fr 90px 1.3fr 34px;
  gap: 8px;
  align-items: center;
  margin-bottom: 8px;
}
.hr-row select, .hr-row input {
  width: 100%;
  padding: 9px 11px;
  border: 1px solid var(--border);
  border-radius: 9px;
  font-family: inherit;
  font-size: .86rem;
  background: #fff;
}

/* ---- marks ---- */
.sc-row {
  display: grid;
  grid-template-columns: 1.4fr 100px 1.2fr;
  gap: 8px;
  align-items: center;
  margin-bottom: 7px;
}
.sc-row > span { font-size: .9rem; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.sc-row input {
  width: 100%;
  padding: 9px 11px;
  border: 1px solid var(--border);
  border-radius: 9px;
  font-family: inherit;
  font-size: .88rem;
}
.sc-row .sc-marks { text-align: center; font-weight: 600; }

@media (max-width: 760px) {
  .hr-row { grid-template-columns: 1fr 1fr; }
  .hr-row .s-del { grid-column: 1 / -1; }
  .sc-row { grid-template-columns: 1fr 90px; }
  .sc-row .sc-remark { grid-column: 1 / -1; }
  .tt-slot { flex-wrap: wrap; }
  .tt-teacher { width: 100%; }
}


/* student's own attendance + sections on my-batch */
.mb-sec { margin-top: 26px; padding-top: 22px; border-top: 1px solid var(--border); }
.mb-sec > h3 {
  font-size: .74rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .09em;
  color: var(--muted);
  margin-bottom: 12px;
}
.mb-att { display: flex; gap: 22px; flex-wrap: wrap; align-items: flex-start; }
.mb-att-big {
  background: #e4f5ec;
  border-radius: 14px;
  padding: 16px 24px;
  text-align: center;
  flex: 0 0 auto;
}
.mb-att-big span { display: block; font-size: 2.1rem; font-weight: 700; color: #14804a; line-height: 1.1; }
.mb-att-big small { color: var(--muted); font-size: .76rem; }
.mb-att-big.low { background: #fdecee; }
.mb-att-big.low span { color: var(--q-not-answered); }

.mb-att-subs { display: flex; gap: 10px; flex-wrap: wrap; flex: 1 1 240px; }
.mb-att-subs > div {
  background: var(--bg-soft);
  border-radius: 11px;
  padding: 11px 16px;
  min-width: 104px;
}
.mb-att-subs b { display: block; font-size: .82rem; }
.mb-att-subs span { font-size: 1.1rem; font-weight: 700; color: #14804a; }
.mb-att-subs span.low { color: var(--q-not-answered); }
.mb-att-subs small { display: block; color: var(--muted); font-size: .72rem; }

/* =========================================================
   PROFILE  (.pf-*)  and  SCORE HISTORY  (.sc-*)
   profile.html · scores.html
   ========================================================= */

.pf-main { padding: 34px 0 70px; background: var(--bg-soft); min-height: 60vh; }
.pf-state { max-width: 560px; margin: 40px auto; text-align: center; }
.pf-error {
  margin: 18px 0 0; padding: 12px 16px; border-radius: 12px;
  background: #fdecee; color: #a01427; font-size: .9rem;
}

.pf-top { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; margin-bottom: 18px; }
.pf-h1 { font-size: clamp(1.55rem, 3.4vw, 2.05rem); font-weight: 700; margin: 0; letter-spacing: -.02em; }
.pf-top-link { flex: none; }

/* ---------- identity ---------- */
.pf-identity {
  display: grid; grid-template-columns: auto 1fr auto; gap: 26px; align-items: center;
  background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 26px 28px; margin-bottom: 20px;
}
.pf-avatar {
  width: 112px; height: 112px; border-radius: 50%; background: var(--primary); color: #fff;
  display: grid; place-items: center; font-size: 2.9rem; font-weight: 700; line-height: 1;
}
.pf-name { font-size: 1.6rem; font-weight: 700; margin: 0 0 4px; letter-spacing: -.02em; }
.pf-email { color: var(--muted); margin: 0 0 12px; font-size: .93rem; word-break: break-word; }
.pf-since { display: flex; align-items: center; gap: 8px; margin: 0; font-size: .82rem; color: var(--muted); }
.pf-since svg { width: 17px; height: 17px; color: var(--primary); flex: none; }
.pf-since b { display: block; color: var(--primary); font-weight: 600; font-size: .93rem; }
.pf-quote {
  max-width: 250px; margin: 0; padding-left: 20px; color: var(--muted);
  font-size: .9rem; line-height: 1.6; position: relative;
}
.pf-quote-mark {
  display: block; font-family: "Poppins", "Noto Sans Devanagari", "Segoe UI", system-ui, sans-serif;
  font-size: 2.4rem; line-height: 1; color: var(--border); margin-bottom: -6px;
}

/* ---------- cards ---------- */
.pf-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; }
.pf-card {
  background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 20px 22px; min-width: 0;
}
.pf-card-head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding-bottom: 14px; margin-bottom: 14px; border-bottom: 1px solid var(--border);
}
.pf-card-head h3 { display: flex; align-items: center; gap: 10px; margin: 0; font-size: 1rem; font-weight: 600; }
.pf-ico { width: 26px; height: 26px; border-radius: 8px; display: grid; place-items: center; flex: none; }
.pf-ico svg { width: 16px; height: 16px; }
.pf-ico-blue { background: var(--primary-light); color: var(--primary); }
.pf-ico-green { background: #e6f5ec; color: #14804a; }
.pf-ico-indigo { background: #eeeaff; color: #5b3dd4; }
.pf-ico-orange { background: #fdeee1; color: var(--accent-deep); }
.pf-all {
  background: none; border: 0; padding: 0; cursor: pointer; flex: none;
  color: var(--primary); font: inherit; font-size: .82rem; font-weight: 600; text-decoration: none;
}
.pf-all:hover { text-decoration: underline; }

/* ---------- a list row ---------- */
.pf-list { display: flex; flex-direction: column; gap: 4px; }
.pf-row { display: flex; align-items: center; gap: 13px; padding: 9px 0; }
.pf-row + .pf-row { border-top: 1px solid var(--bg-soft); }
.pf-tag {
  width: 40px; height: 40px; border-radius: 11px; flex: none;
  display: grid; place-items: center; font-size: .65rem; font-weight: 700; letter-spacing: .01em;
}
.pf-tag svg { width: 19px; height: 19px; }
.pf-tag.t-b { background: var(--primary-light); color: var(--primary); }
.pf-tag.t-g { background: #e6f5ec; color: #14804a; }
.pf-tag.t-v { background: #eeeaff; color: #5b3dd4; }
.pf-tag.t-o { background: #fdeee1; color: var(--accent-deep); }
.pf-tag.t-p { background: #e8eefc; color: #2a4fbf; }
.pf-row-main { flex: 1; min-width: 0; }
.pf-row-main strong { display: block; font-size: .88rem; font-weight: 600; line-height: 1.35; }
.pf-row-main small { display: block; color: var(--muted); font-size: .76rem; margin-top: 2px; }
.pf-chip {
  flex: none; font-size: .7rem; font-weight: 600; padding: 4px 10px; border-radius: 999px; white-space: nowrap;
}
.pf-chip.ok { background: #e6f5ec; color: #14804a; }
.pf-chip.wait { background: #fdf3e0; color: #92600b; }
.pf-chip.bad { background: #fdecee; color: #a01427; }

/* ---------- a table ---------- */
.pf-table { width: 100%; border-collapse: collapse; font-size: .84rem; }
.pf-table th {
  text-align: left; font-weight: 500; color: var(--muted); font-size: .76rem;
  padding: 0 10px 9px 0; white-space: nowrap;
}
.pf-table td { padding: 10px 10px 10px 0; border-top: 1px solid var(--bg-soft); }
.pf-table tbody tr:first-child td { border-top: 0; }
.pf-table a { color: var(--text); text-decoration: none; font-weight: 500; }
.pf-table a:hover { color: var(--primary); }
.pf-num { white-space: nowrap; font-variant-numeric: tabular-nums; }
.pf-num.up { color: #14804a; font-weight: 600; }
.pf-num.down { color: var(--accent-deep); font-weight: 600; }

/* ---------- attendance rings ---------- */
.pf-att-batch { margin: 0 0 14px; font-size: .8rem; color: var(--muted); }
.pf-rings { display: flex; gap: 10px; justify-content: space-around; flex-wrap: wrap; }
.pf-ring { text-align: center; min-width: 92px; flex: 1; }
.pf-ring-label { display: block; font-size: .74rem; color: var(--muted); margin-bottom: 6px; }
.pf-ring-svg { width: 84px; height: 84px; transform: rotate(-90deg); }
.pf-ring-track { fill: none; stroke: var(--bg-soft); stroke-width: 9; }
.pf-ring-fill {
  fill: none; stroke: var(--primary); stroke-width: 9; stroke-linecap: round;
  transition: stroke-dasharray .5s ease;
}
.pf-ring-svg.low .pf-ring-fill { stroke: var(--q-not-answered); }
.pf-ring-text {
  transform: rotate(90deg); transform-origin: 40px 40px; fill: var(--text);
  font-size: 17px; font-weight: 700; text-anchor: middle; dominant-baseline: central;
}
.pf-ring small { display: block; color: var(--muted); font-size: .72rem; margin-top: 2px; }
.pf-att-subs { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--bg-soft); }
.pf-att-subs > div { min-width: 88px; }
.pf-att-subs b { display: block; font-size: .78rem; }
.pf-att-subs span { font-size: 1.02rem; font-weight: 700; color: #14804a; }
.pf-att-subs span.low { color: var(--q-not-answered); }
.pf-att-subs small { display: block; color: var(--muted); font-size: .7rem; }

/* ---------- footer links ---------- */
.pf-links { display: flex; flex-wrap: wrap; gap: 10px 22px; margin: 26px 0 18px; }
.pf-links a { color: var(--muted); font-size: .86rem; text-decoration: none; }
.pf-links a:hover { color: var(--primary); text-decoration: underline; }

/* =========================================================
   SCORE HISTORY — scores.html
   ========================================================= */

.sc-back { display: inline-block; color: var(--muted); font-size: .84rem; text-decoration: none; margin-bottom: 6px; }
.sc-back:hover { color: var(--primary); }

.sc-filters { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 18px; }
.sc-chip {
  border: 1px solid var(--border); background: var(--bg); color: var(--muted);
  border-radius: 999px; padding: 7px 15px; font: inherit; font-size: .8rem; font-weight: 500; cursor: pointer;
}
.sc-chip:hover { border-color: var(--primary); color: var(--primary); }
.sc-chip.on { background: var(--primary); border-color: var(--primary); color: #fff; }

.sc-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 14px; margin-bottom: 20px; }
.sc-tile {
  background: var(--bg); border: 1px solid var(--border); border-radius: 14px; padding: 16px 18px;
}
.sc-tile span { display: block; font-size: .76rem; color: var(--muted); }
.sc-tile strong { display: block; font-size: 1.65rem; font-weight: 700; letter-spacing: -.02em; margin-top: 4px; }
.sc-tile small { display: block; font-size: .7rem; color: var(--muted); margin-top: 2px; }
.sc-tile.up strong { color: #14804a; }
.sc-tile.down strong { color: var(--accent-deep); }

.sc-chart-card { margin-bottom: 20px; }
.sc-legend, .sc-count { font-size: .78rem; color: var(--muted); flex: none; }
.sc-chart-wrap { position: relative; }
.sc-svg { width: 100%; height: auto; display: block; overflow: visible; }
.sc-grid { stroke: var(--border); stroke-width: 1; }
.sc-axis { fill: var(--muted); font-size: 11px; }
.sc-area { fill: var(--primary); opacity: .08; }
.sc-line { fill: none; stroke: var(--primary); stroke-width: 2.5; stroke-linejoin: round; stroke-linecap: round; }
.sc-dot { fill: #fff; stroke: var(--primary); stroke-width: 2.5; }
.sc-dot.on { fill: var(--primary); r: 6; }
.sc-hit { fill: transparent; cursor: pointer; }
.sc-tip {
  position: absolute; top: 8px; transform: translateX(-50%); pointer-events: none;
  background: var(--dark); color: #fff; border-radius: 10px; padding: 9px 12px;
  font-size: .76rem; line-height: 1.5; white-space: nowrap; z-index: 3; box-shadow: var(--shadow-lg);
}
.sc-tip b { display: block; font-size: .8rem; margin-bottom: 2px; }
.sc-tip span { display: block; opacity: .82; }

.sc-two { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; margin-bottom: 20px; }

.sc-bars { display: flex; flex-direction: column; gap: 15px; }
.sc-bar-top { display: flex; justify-content: space-between; align-items: baseline; font-size: .85rem; }
.sc-bar-top span { font-weight: 700; font-variant-numeric: tabular-nums; }
.sc-bar-track { height: 9px; border-radius: 999px; background: var(--bg-soft); overflow: hidden; margin: 6px 0 4px; }
.sc-bar-track i { display: block; height: 100%; border-radius: 999px; transition: width .5s ease; }
.sc-bar-track i.good { background: #14804a; }
.sc-bar-track i.mid { background: var(--accent); }
.sc-bar-track i.weak { background: var(--q-not-answered); }
.sc-bar small { color: var(--muted); font-size: .73rem; }

.sc-stack { display: flex; height: 14px; border-radius: 999px; overflow: hidden; background: var(--bg-soft); }
.sc-stack i { display: block; height: 100%; }
.sc-stack i.good { background: #14804a; }
.sc-stack i.weak { background: var(--q-not-answered); }
.sc-stack i.skip { background: var(--q-not-visited); }
.sc-keys { list-style: none; margin: 16px 0 0; padding: 0; display: flex; flex-direction: column; gap: 9px; }
.sc-keys li { display: flex; align-items: center; gap: 9px; font-size: .84rem; color: var(--muted); }
.sc-keys b { color: var(--text); font-variant-numeric: tabular-nums; }
.sc-keys em { margin-left: auto; font-style: normal; font-weight: 600; color: var(--text); }
.sc-key { width: 11px; height: 11px; border-radius: 4px; flex: none; }
.sc-key.good { background: #14804a; }
.sc-key.weak { background: var(--q-not-answered); }
.sc-key.skip { background: var(--q-not-visited); }
.sc-foot { margin: 14px 0 0; font-size: .75rem; color: var(--muted); }

/* The history table is the one thing here that genuinely cannot shrink to a
   phone, so it scrolls inside its own box rather than widening the page. */
.sc-table-wrap { overflow-x: auto; }
.sc-history { min-width: 720px; }
.sc-attempt, .sc-auto {
  display: inline-block; font-size: .66rem; font-weight: 600; padding: 2px 7px;
  border-radius: 999px; vertical-align: middle;
}
.sc-attempt { background: var(--bg-soft); color: var(--muted); }
.sc-auto { background: #fdf3e0; color: #92600b; }
.sc-view { color: var(--primary) !important; font-weight: 600; }

/* ---------- responsive ---------- */
@media (max-width: 900px) {
  .pf-grid, .sc-two { grid-template-columns: 1fr; }
  .pf-identity { grid-template-columns: auto 1fr; gap: 20px; }
  .pf-quote { grid-column: 1 / -1; max-width: none; padding-left: 0; border-top: 1px solid var(--border); padding-top: 14px; }
  .pf-quote-mark { display: inline; font-size: 1.6rem; margin-right: 4px; }
}
@media (max-width: 560px) {
  .pf-main { padding: 22px 0 50px; }
  .pf-identity { grid-template-columns: 1fr; text-align: center; padding: 22px 18px; }
  .pf-avatar { width: 88px; height: 88px; font-size: 2.2rem; margin: 0 auto; }
  .pf-since { justify-content: center; }
  .pf-top { flex-direction: column; align-items: stretch; }
  .pf-card { padding: 17px 16px; }
  .pf-rings { gap: 4px; }
  .pf-ring { min-width: 78px; }
  .pf-ring-svg { width: 70px; height: 70px; }
  .sc-tile strong { font-size: 1.35rem; }
}

/* ---------- destructive controls in the console ----------
   Deliberately quiet, not red-by-default. These sit next to ordinary buttons
   the owner presses every day; a permanently alarming control stops reading as
   a warning within a week. The button turns red only once it is armed and the
   next click really does delete. */
.ad-danger {
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid var(--border);
}
.ad-danger-btn {
  color: #a01427;
  border-color: #f3c9cf;
}
.ad-danger-btn:hover {
  background: #fdecee;
  border-color: #a01427;
}
/* Armed: the next click destroys something. */
.ad-danger-btn[data-armed="1"],
.ad-danger-box .ad-danger-btn:focus-visible {
  background: #a01427;
  border-color: #a01427;
  color: #fff;
}
.ad-danger-box {
  border-color: #f3c9cf;
  background: #fffafa;
}
.ad-danger-box h3 { color: #a01427; }

/* =========================================================
   BATCHES ON A COURSE PAGE  (.pb-*)
   Rendered by the shared block in js/vb-firebase.js. The host section carries
   `hidden` until there is something real to show, and [hidden] is
   `display:none !important` globally, so an empty response leaves the page
   exactly as it was.
   ========================================================= */
.pb-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 18px;
  margin-top: 26px;
}
.pb-card {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 22px 22px 18px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.pb-card h3 { margin: 0; font-size: 1.05rem; font-weight: 600; }
.pb-meta { margin: 0; color: var(--muted); font-size: .84rem; }
.pb-card .pb-join { margin-top: 14px; align-self: flex-start; }
.pb-msg {
  margin: 8px 0 0; font-size: .8rem; color: var(--muted); min-height: 1.1em;
}

/* ---------- admin: is this batch on the website? ---------- */
.ab-public {
  margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--border);
}
.ab-public-row {
  display: flex; align-items: flex-start; gap: 10px; cursor: pointer;
}
.ab-public-row input { margin-top: 3px; width: 16px; height: 16px; flex: none; }
.ab-public-row b { display: block; font-size: .9rem; font-weight: 600; }
.ab-public-row small { display: block; color: var(--muted); font-size: .78rem; margin-top: 2px; }
.ab-public-note {
  margin: 8px 0 0 26px; color: var(--muted); font-size: .78rem; line-height: 1.55;
}
.ab-public-note b { color: var(--text); }

/* =========================================================
   TEST SERIES + ACCESS CODES
   .mt-code* on my-tests.html · .ts-* / .tc-* in the employee panel
   ========================================================= */

/* ---------- student: redeem a code ---------- */
.mt-code {
  margin-top: 32px;
  background: var(--bg-soft);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 22px 24px;
}
.mt-code h3 { margin: 0 0 4px; font-size: 1rem; font-weight: 600; }
.mt-code > p { margin: 0 0 14px; color: var(--muted); font-size: .86rem; }
.mt-code-row { display: flex; gap: 10px; flex-wrap: wrap; }
.mt-code-row input {
  flex: 1 1 180px; max-width: 260px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 1.05rem; letter-spacing: .12em; text-transform: uppercase;
  padding: 11px 14px; border: 1px solid var(--border); border-radius: 12px; background: var(--bg);
}
.mt-code-row input:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
.mt-code-msg { margin: 12px 0 0; font-size: .85rem; }
.mt-code-msg.ok { color: #14804a; }
.mt-code-msg.bad { color: #a01427; }

/* ---------- employee: series + code forms ---------- */
.tp-series-form, .tp-code-form {
  display: flex; flex-wrap: wrap; gap: 14px; align-items: flex-end; margin-top: 16px;
}
.tp-series-form label, .tp-code-form label {
  display: flex; flex-direction: column; gap: 5px;
  font-size: .78rem; color: var(--muted); flex: 1 1 150px;
}
.tp-series-form input, .tp-series-form select,
.tp-code-form input, .tp-code-form select {
  padding: 9px 11px; border: 1px solid var(--border); border-radius: 10px;
  font: inherit; font-size: .88rem; background: var(--bg); color: var(--text);
}
.tp-series-form .tp-check, .tp-code-form .tp-check {
  flex-direction: row; align-items: center; gap: 8px; flex: 0 0 auto; padding-bottom: 9px;
}
.tp-check input { width: 16px; height: 16px; }

/* ---------- series rows ---------- */
.ts-rows, .tc-rows { display: flex; flex-direction: column; gap: 2px; margin-top: 18px; }
.ts-row, .tc-row {
  display: flex; align-items: center; gap: 12px;
  padding: 11px 0; border-top: 1px solid var(--bg-soft);
}
.ts-row > div, .tc-row > div { flex: 1; min-width: 0; }
.ts-row strong, .tc-row strong { display: block; font-size: .9rem; font-weight: 600; }
.ts-others { opacity: .72; }
.ts-lock {
  font-size: .72rem; color: var(--muted); background: var(--bg-soft);
  padding: 4px 10px; border-radius: 999px; white-space: nowrap;
}

/* ---------- codes ---------- */
.tc-code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .95rem; font-weight: 700; letter-spacing: .1em;
  background: var(--primary-light); color: var(--primary);
  padding: 6px 11px; border-radius: 9px; white-space: nowrap;
}
.tc-state {
  font-size: .7rem; font-weight: 600; padding: 4px 10px;
  border-radius: 999px; white-space: nowrap;
}
.tc-state.live { background: #e6f5ec; color: #14804a; }
.tc-state.expired, .tc-state.used-up { background: var(--bg-soft); color: var(--muted); }
.tc-state.revoked { background: #fdecee; color: #a01427; }

@media (max-width: 560px) {
  .tp-series-form label, .tp-code-form label { flex: 1 1 100%; }
  .ts-row, .tc-row { flex-wrap: wrap; }
}

/* ---------- employee sign-in: one column, no proof panel ----------
   register.html keeps its split layout — it is selling admission to strangers.
   employee.html is not: everyone who reaches it already works here, so the
   owner had the eyebrow, the heading and the four bullets removed. That leaves
   `.auth-split`'s 1.05fr / 0.95fr grid with one child and a dead half, so
   collapse it and centre what is left.

   `.emp-panel` and `.emp-list` in this stylesheet are now unused — nothing in
   public/ carries those classes. Left in place rather than deleted mid-session;
   safe to remove. `.auth-panel-eyebrow` and `.auth-panel-head` are still live
   on register.html, so those must stay. */
.auth-split.emp-split {
  grid-template-columns: 1fr;
  /* Without the tall gradient panel there is nothing to fill a full viewport,
     and a lone card floating in the middle of 100dvh reads as a broken page. */
  min-height: 0;
  padding: clamp(40px, 9vh, 96px) 0;
}
.emp-split .auth-side { padding: 0 24px; }

/* =========================================================
   LOADING STATES  (.sk-* skeletons · .ld-* gates and rows)

   Approved from design-drafts/loading-states.html. The nine loading states on
   the site are three different problems and get three different treatments:

     1. A page whose shape is known (profile, scores, my-tests, my-batch,
        result) gets a SKELETON of that shape, so the page does not jump when
        the data lands.
     2. An access check (admin, employee, checkout) gets only a mark and a line.
        A skeleton there would promise a page that may never come — an
        unapproved teacher would watch a fake dashboard assemble and then be
        told "not authorised".
     3. The exam player keeps its plain spinner and NO shimmer: a student about
        to sit a timed paper must not see anything that reads as a glitch.

   The skeleton is decoration. Every use pairs it with `aria-hidden="true"` and
   a visually-hidden `role="status"` line, so a screen reader hears one sentence
   instead of nothing.
   ========================================================= */

.sk {
  background: var(--skeleton);
  border-radius: 8px;
  position: relative;
  overflow: hidden;
}
.sk::after {
  content: "";
  position: absolute;
  inset: 0;
  transform: translateX(-100%);
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .9), transparent);
  animation: skShimmer 1.4s ease-in-out infinite;
}
@keyframes skShimmer { to { transform: translateX(100%); } }

/* A moving highlight is a promise that something is coming, so it is not
   dropped for reduced-motion — it becomes a slow fade instead of a sweep. */
@media (prefers-reduced-motion: reduce) {
  .sk::after { animation: none; }
  .sk { animation: skPulse 1.8s ease-in-out infinite; }
  @keyframes skPulse { 50% { opacity: .55; } }
}

.sk-line { height: 12px; }
.sk-line.sk-sm { height: 10px; }
.sk-line.sk-lg { height: 18px; }
.sk-title { height: 26px; border-radius: 9px; }
.sk-circle { border-radius: 50%; }
.sk-chip { height: 26px; width: 74px; border-radius: 999px; }
.sk-box { border-radius: 12px; }
.sk-w90 { width: 90%; } .sk-w70 { width: 70%; }
.sk-w55 { width: 55%; } .sk-w40 { width: 40%; } .sk-w25 { width: 25%; }
.sk-stack { display: flex; flex-direction: column; gap: 9px; }
.sk-row { display: flex; align-items: center; gap: 13px; }
.sk-grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.sk-card { border: 1px solid var(--border); border-radius: 12px; padding: 16px; }

/* ---------- 1. skeleton page wrappers ---------- */
/* Fills roughly what the loaded page will, so the footer is not left
   floating mid-screen above a white void — which is what "looks pathetic"
   actually meant. */
.sk-page { padding: 8px 0 40px; }
.sk-head { display: flex; gap: 20px; align-items: center; margin-bottom: 22px; }
.sk-avatar { width: 74px; height: 74px; flex: none; }
.sk-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 14px; }

/* ---------- 2. the access gate ---------- */
.ld-gate {
  display: grid;
  place-items: center;
  gap: 16px;
  padding: clamp(48px, 12vh, 110px) 20px;
  text-align: center;
}
.ld-mark {
  width: 46px; height: 46px; border-radius: 14px;
  background: var(--primary-light);
  display: grid; place-items: center;
  position: relative;
}
.ld-mark svg { width: 24px; height: 24px; color: var(--primary); }
.ld-mark::before {
  content: "";
  position: absolute; inset: -6px;
  border-radius: 20px;
  border: 2px solid var(--primary);
  opacity: 0;
  animation: ldRing 1.6s ease-out infinite;
}
@keyframes ldRing {
  0%   { transform: scale(.86); opacity: .5; }
  70%  { transform: scale(1.12); opacity: 0; }
  100% { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) { .ld-mark::before { animation: none; } }
.ld-gate p { margin: 0; color: var(--muted); font-size: .92rem; }

/* ---------- 3. the exam player's extra line ---------- */
.tp-load-note {
  margin: 0;
  color: var(--muted);
  font-size: .84rem;
  text-align: center;
  max-width: 34ch;
}

/* ---------- 4. rows inside a panel that has already drawn ---------- */
.ld-rows { display: flex; flex-direction: column; gap: 2px; }
.ld-rows > div {
  display: flex; align-items: center; gap: 13px;
  padding: 12px 0; border-top: 1px solid var(--bg-soft);
}
.ld-rows > div:first-child { border-top: 0; }
.ld-thumb { width: 38px; height: 38px; border-radius: 11px; flex: none; }

/* ---------- the sentence a screen reader actually hears ---------- */
.ld-sr {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

@media (max-width: 560px) {
  .sk-grid2 { grid-template-columns: 1fr; }
  .sk-head { gap: 14px; }
  .sk-avatar { width: 58px; height: 58px; }
}

/* =========================================================
   TEACHER SIGN-IN (.tl-*)
   Its own page furniture â€” no site header, no footer nav. Nobody browses
   here; the only way out is back to the student sign-in.
   ========================================================= */
.tl-page {
  position: relative;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  background: #f4f7fd;
  overflow: hidden;
}

/* the two soft wave sweeps behind everything */
.tl-page::before,
.tl-page::after {
  content: "";
  position: absolute;
  border-radius: 50%;
  pointer-events: none;
}
.tl-page::before {
  width: 1100px; height: 1100px;
  right: -420px; top: -560px;
  background: radial-gradient(circle, rgba(74, 124, 232, .07) 0%, transparent 62%);
}
.tl-page::after {
  width: 900px; height: 900px;
  left: -420px; bottom: -520px;
  background: radial-gradient(circle, rgba(74, 124, 232, .06) 0%, transparent 62%);
}

/* ---------- top bar ---------- */
.tl-top {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding: 26px clamp(22px, 5vw, 66px) 0;
}
.tl-brand {
  font-size: clamp(1.3rem, 2.4vw, 1.65rem);
  font-weight: 800;
  letter-spacing: -.02em;
  color: var(--dark);
}
.tl-brand span { color: var(--primary); }

.tl-student {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-size: .95rem;
  font-weight: 500;
  color: #3f4a63;
  transition: color .18s ease;
}
.tl-student svg { width: 19px; height: 19px; color: var(--primary); }
.tl-student:hover { color: var(--primary); }

/* ---------- the two columns ---------- */
.tl-main {
  position: relative;
  z-index: 2;
  flex: 1 1 auto;
  display: grid;
  grid-template-columns: minmax(360px, 480px) minmax(0, 1fr);
  align-items: center;
  gap: clamp(28px, 5vw, 72px);
  padding: clamp(24px, 4vw, 46px) clamp(22px, 5vw, 66px);
}

/* the dotted grid at the far left, as in the reference */
.tl-main::before {
  content: "";
  position: absolute;
  left: 10px;
  top: 50%;
  transform: translateY(-58%);
  width: 96px; height: 96px;
  background-image: radial-gradient(#c3d2ea 1.6px, transparent 1.6px);
  background-size: 16px 16px;
  opacity: .85;
  pointer-events: none;
}

/* ---------- the card ---------- */
.tl-card {
  background: #fdfdff;
  border-radius: 22px;
  padding: clamp(34px, 4vw, 52px) clamp(26px, 3.4vw, 46px);
  box-shadow: 0 18px 50px rgba(43, 79, 158, .10), 0 2px 8px rgba(43, 79, 158, .05);
  text-align: center;
  justify-self: center;
  width: 100%;
  max-width: 470px;
}

.tl-ico {
  width: 82px; height: 82px;
  margin: 0 auto 22px;
  border-radius: 50%;
  background: #e7effc;
  color: var(--primary);
  display: grid;
  place-items: center;
}
.tl-ico svg { width: 38px; height: 38px; }
.tl-ico.ok { background: #e4f5ec; color: #14804a; }
.tl-ico.wait { background: #fff2e4; color: var(--accent-deep); }

.tl-h1 {
  font-size: clamp(1.8rem, 3vw, 2.3rem);
  font-weight: 700;
  letter-spacing: -.02em;
  color: var(--dark);
  line-height: 1.2;
}
.tl-h1 span { color: var(--primary); }

.tl-sub {
  color: #6b7590;
  font-size: .98rem;
  line-height: 1.6;
  margin: 10px auto 0;
  max-width: 30ch;
}
.tl-sub b { color: var(--text); font-weight: 600; }

/* ---------- the one control ---------- */
.tl-google {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  width: 100%;
  margin-top: 30px;
  background: #fff;
  border: 1px solid #e3e9f4;
  border-radius: 14px;
  padding: 17px 22px;
  font-size: 1.02rem;
  font-weight: 600;
  color: var(--dark);
  box-shadow: 0 2px 8px rgba(43, 79, 158, .05);
  transition: border-color .18s ease, box-shadow .18s ease, transform .18s ease;
}
.tl-google svg { width: 23px; height: 23px; flex: 0 0 auto; }
.tl-google:hover {
  border-color: #c3d3ee;
  box-shadow: 0 8px 22px rgba(43, 79, 158, .12);
  transform: translateY(-1px);
}
.tl-google:disabled { opacity: .6; transform: none; }

.tl-primary {
  width: 100%;
  margin-top: 26px;
  background: var(--primary);
  color: #fff;
  border: none;
  border-radius: 14px;
  padding: 16px 22px;
  font-size: 1rem;
  font-weight: 600;
  transition: background .18s ease, transform .18s ease;
}
.tl-primary:hover { background: var(--primary-dark); transform: translateY(-1px); }

.tl-ghost {
  width: 100%;
  margin-top: 10px;
  background: none;
  border: 1px solid #e3e9f4;
  border-radius: 12px;
  padding: 13px 22px;
  font-size: .92rem;
  font-weight: 600;
  color: #6b7590;
  transition: border-color .18s ease, color .18s ease;
}
.tl-ghost:hover { border-color: var(--q-not-answered); color: var(--q-not-answered); }

.tl-link-btn {
  padding: 4px 0;
  border: 0;
  background: none;
  color: #1658d8;
  font-size: .82rem;
  font-weight: 600;
  cursor: pointer;
}
.tl-link-btn:hover, .tl-link-btn:focus-visible { text-decoration: underline; text-underline-offset: 2px; }
.tl-link-btn:disabled { color: #9aa5bd; cursor: default; text-decoration: none; }

/* ---------- divider + trust line ---------- */
.tl-or {
  display: flex;
  align-items: center;
  gap: 16px;
  margin: 26px 0;
  color: #9aa4bd;
  font-size: .92rem;
}
.tl-or::before, .tl-or::after {
  content: "";
  flex: 1;
  height: 1px;
  background: #e6ebf5;
}

.tl-trust {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: .95rem;
  font-weight: 500;
  color: #3f4a63;
}
.tl-trust svg { width: 21px; height: 21px; color: var(--primary); }

.tl-note {
  background: #f4f7fd;
  border: 1px solid #e6ebf5;
  border-radius: 12px;
  padding: 14px 16px;
  font-size: .87rem;
  color: #6b7590;
  line-height: 1.65;
  margin-top: 18px;
  text-align: left;
}
.tl-note b, .tl-note strong { color: var(--text); }

/* the sign-in failure line lives inside this card too */
.tl-card .google-note { margin-top: 12px; }

/* ---------- illustration ---------- */
.tl-art { justify-self: center; width: 100%; max-width: 720px; }
.tl-art svg { width: 100%; height: auto; display: block; }

/* ---------- footer ---------- */
.tl-foot {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 12px 22px 30px;
  text-align: center;
}
.tl-foot svg { width: 26px; height: 26px; color: var(--primary); }
.tl-foot p { font-size: .88rem; color: #7c86a0; }

/* ---------- responsive ---------- */
@media (max-width: 1080px) {
  .tl-main { grid-template-columns: 1fr; gap: 34px; }
  /* The card comes FIRST. Someone here to sign in should not scroll past a
     picture to reach the button. */
  .tl-card { order: -1; }
  .tl-art { max-width: 560px; }
  .tl-main::before { display: none; }
}

@media (max-width: 560px) {
  .tl-top { padding: 20px 20px 0; }
  .tl-student span { display: none; }
  .tl-card { padding: 32px 22px; border-radius: 18px; }
  .tl-ico { width: 68px; height: 68px; }
  .tl-ico svg { width: 32px; height: 32px; }
  .tl-art { max-width: 420px; }
}

/* =========================================================
   STICKY FOOTER
   A short page used to leave the dark footer stranded halfway up the screen
   with a white void beneath it. That is what the owner saw on the loading
   skeleton and called a "black line" — it was the footer, floating.

   Fixed here rather than by giving each page its own min-height: the skeleton
   pages, the empty states and the access gates are all short, and any
   arithmetic tuned to one of them is wrong for the others and rots the moment
   padding changes.

   test.html is excluded on purpose. The exam player has no header and no
   footer, sets its own full-screen layout, and is the one page where a layout
   surprise costs a student their paper.
   ========================================================= */
/* admin.html (.ac-body) is excluded for the same reason as test.html: the owner
   console is an app shell with its own full-height layout and no site header or
   footer to push down. Naming it HERE rather than overriding further down the
   file matters — an override would have identical specificity (0,1,1) and would
   win on source order alone, so the next person appending CSS could undo it
   without touching either rule. */
body:not(.tp-body):not(.ac-body) {
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}
body:not(.tp-body):not(.ac-body) > main {
  flex: 1 0 auto;
}

/* The real illustration replaces the placeholder SVG the moment it loads. */
.tl-art img { width: 100%; height: auto; display: block; }
.tl-art img:not([src]) { display: none; }

/* Teacher sign-in: the owner supplied the complete desktop composition. Do not
   approximate its layout in CSS. The image is the visual layer and the real
   form controls sit precisely over the matching controls so sign-in remains
   functional without introducing a second card or a taller-than-screen layout. */
/* THE SURROUND IS COLOUR-MATCHED TO THE ARTWORK'S OWN EDGES.

   The stage below is locked to the reference image's 1672:941 ratio, so on a
   window of any other ratio there is space beside it. Two earlier attempts at
   filling that space both showed a visible seam:

     - a flat #010d0e: measured against the artwork, its LEFT edge is #060e0f
       (lighter than that) and its RIGHT edge is #01090b (darker), so one flat
       colour cannot match both sides and a band showed on at least one;
     - a blurred blow-up of the artwork: no colour mismatch, but blur keeps the
       picture's structure, so the eye read it as two smeared panels.

   The edge colours were sampled off the image itself (average of the outer
   40px columns), and the page now runs a horizontal gradient between exactly
   those two values. Each bar therefore meets the artwork at its own colour and
   the join disappears. No blur, no structure, nothing to notice.

   IF THE ARTWORK IS EVER REPLACED, RE-SAMPLE THESE TWO VALUES. They are
   properties of that specific image, not general theme colours. */
.teacher-login-page {
  position: relative;
  min-height: 100svh;
  background: linear-gradient(to right, #070f0f 0%, #070f0f 34%, #010a0b 66%, #010a0b 100%);
  color: #f8fafc;
  /* centre the aspect-locked stage — see .tl-main below */
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.teacher-login-page::before,
.teacher-login-page::after { display: none; }
.teacher-login-page .tl-top,
.teacher-login-page .tl-art,
.teacher-login-page .tl-foot { display: none; }
/* THE STAGE IS LOCKED TO THE ARTWORK'S OWN ASPECT RATIO.

   It used to be `width:100vw; height:100svh` with `background-size:100% 100%`,
   which scales each axis INDEPENDENTLY — so the composition only rendered
   truthfully on a viewport that happened to be exactly 1672:941 (16:9).
   A maximised browser is never 16:9: tabs, address bar and bookmarks eat
   110-160px of height, so a 1920x1080 screen gives roughly 1920x920 => 1.99,
   and the whole picture was drawn 12% too wide. Measured, at 1835x922: +12%.
   At 1440x900 it went the other way and squashed 10%.

   `min()` keeps the box inside the viewport on whichever axis binds first while
   holding 1672:941 exactly, so the artwork can never distort. Every overlay
   control is positioned in PERCENTAGES OF THIS BOX (#empEmail top:24.87%,
   #empPassword top:41.13%, and the rest), so they scale with the stage and stay
   registered to the drawn controls automatically — that is why the ratio has to
   live here and not on the background alone.

   `background-size: 100% 100%` is now safe and is kept deliberately: the box
   already matches the image, so 100% 100% and `contain` are identical, and this
   form guarantees the overlay percentages map to the image edge-to-edge. */
.teacher-login-page .tl-main {
  position: relative;
  z-index: 1;
  display: block;
  flex: none;
  width: min(100vw, calc(100svh * 1672 / 941));
  height: min(100svh, calc(100vw * 941 / 1672));
  min-height: 0;
  margin: auto;
  padding: 0;
  overflow: hidden;
  background: url("../images/teacher-login-reference.webp") center / 100% 100% no-repeat;
}
.teacher-login-page .tl-main::before { display: none; }
.teacher-login-page .tl-student-portal {
  position: absolute;
  z-index: 4;
  left: 2.4%;
  bottom: 2.8%;
  display: inline-flex;
  align-items: center;
  gap: .45em;
  padding: .68em 1em;
  border: 1px solid rgba(178, 236, 215, .4);
  border-radius: 999px;
  background: rgba(1, 18, 19, .64);
  box-shadow: 0 8px 24px rgba(0, 0, 0, .18);
  color: #e4f8ea;
  font: 600 clamp(10px, .88vw, 15px)/1 Poppins, sans-serif;
  text-decoration: none;
  transition: background .2s ease, border-color .2s ease, transform .2s ease;
}
.teacher-login-page .tl-student-portal:hover,
.teacher-login-page .tl-student-portal:focus-visible {
  border-color: #a7e4ba;
  background: rgba(8, 42, 38, .92);
  transform: translateY(-1px);
}
.teacher-login-page .tl-student-portal svg { width: 1.05em; height: 1.05em; }
.teacher-login-page .tl-card {
  position: absolute;
  inset: 0;
  width: 100%;
  max-width: none;
  height: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  text-align: left;
  justify-self: stretch;
  align-self: stretch;
}
.teacher-login-page .tl-state { width: 100%; }
.teacher-login-page #empSignedOut { display: block; height: 100%; }

/* The supplied artwork already contains the signed-out copy and controls. */
.teacher-login-page #empSignedOut .tl-h1,
.teacher-login-page #empSignedOut .tl-login-form label,
.teacher-login-page #empSignedOut .tl-or,
.teacher-login-page #empSignedOut .tl-trust {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}
.teacher-login-page #empSignedOut .tl-login-form {
  position: static;
  display: block;
  margin: 0;
}
.teacher-login-page #empSignedOut .tl-login-form input {
  position: absolute;
  left: 55.38%;
  width: 32.30%;
  height: 8.08%;
  box-sizing: border-box;
  margin: 0;
  padding: 0 1.42%;
  border: 0;
  border-radius: 12px;
  background: transparent;
  color: #f8fafc;
  font: 500 clamp(12px, 1.35vw, 24px)/1 Poppins, sans-serif;
  outline: 0;
}
.teacher-login-page #empEmail { top: 24.87%; }
.teacher-login-page .tl-password-wrap { position: static; }
.teacher-login-page #empPassword { top: 41.13%; padding-right: 5%; }
.teacher-login-page #empSignedOut .tl-login-form input::placeholder { color: transparent; }
.teacher-login-page #empSignedOut .tl-login-form input:not(:placeholder-shown) { background: rgba(2, 20, 20, .9); }
.teacher-login-page #empSignedOut .tl-login-form input:focus { box-shadow: 0 0 0 2px rgba(167, 228, 186, .75); }
.teacher-login-page .tl-password-wrap button {
  position: absolute;
  z-index: 2;
  top: 42.6%;
  left: 83.4%;
  width: 4.5%;
  height: 5.1%;
  transform: none;
  border: 0;
  background: transparent;
  color: transparent;
  cursor: pointer;
}
.teacher-login-page .tl-forgot,
.teacher-login-page .tl-login-form .tl-primary,
.teacher-login-page .tl-google {
  position: absolute;
  z-index: 2;
  box-sizing: border-box;
  margin: 0;
  border: 0;
  background: transparent;
  box-shadow: none;
  color: transparent;
}
.teacher-login-page .tl-forgot {
  top: 51.9%;
  left: 77.5%;
  width: 10.4%;
  height: 4.2%;
  font-size: 0;
}
.teacher-login-page .tl-login-form .tl-primary {
  top: 58.24%;
  left: 55.38%;
  width: 32.30%;
  height: 7.76%;
  padding: 0;
  cursor: pointer;
}
.teacher-login-page .tl-google {
  top: 73.54%;
  left: 55.38%;
  display: block;
  width: 32.30%;
  height: 8.61%;
  padding: 0;
  cursor: pointer;
}
.teacher-login-page .tl-google svg { display: none; }
/* PLACEHOLDER, not integrated into the artwork — functionality first, owner
   is doing the visual pass later. Floats a plain dark panel near the bottom
   of the locked image so the new signup entry point is at least usable and
   legible on desktop; the mobile layout below already looks normal. */
.teacher-login-page .tl-signup-toggle,
.teacher-login-page #empSignupForm {
  position: absolute;
  z-index: 5;
  left: 55.38%;
  width: 32.30%;
}
.teacher-login-page .tl-signup-toggle { top: 84%; }
.teacher-login-page #empSignupForm:not([hidden]) {
  top: 12%;
  bottom: 4%;
  overflow-y: auto;
  padding: 16px;
  border-radius: 12px;
  background: rgba(1, 12, 13, .94);
  box-shadow: 0 12px 30px rgba(0, 0, 0, .4);
}
.teacher-login-page #empSignupForm label { color: #f8fafc; }
.teacher-login-page #empSignupForm input {
  width: 100%;
  height: 46px;
  margin: 6px 0 14px;
  padding: 0 12px;
  border: 1px solid rgba(180, 224, 222, .3);
  border-radius: 8px;
  background: rgba(1, 19, 20, .8);
  color: #f8fafc;
  font-size: .92rem;
}
.teacher-login-page #empSignupForm .tl-primary { margin-top: 4px; }
.teacher-login-page .tl-link-btn { color: #a7e4ba; }
.teacher-login-page .google-note:not([hidden]) {
  position: absolute;
  z-index: 3;
  top: 67%;
  left: 55.38%;
  width: 32.30%;
  margin: 0;
  color: #f5b8b8;
  font-size: clamp(10px, .9vw, 14px);
  text-align: center;
}

/* The existing approved/pending states remain real HTML cards, rather than
   showing the signed-out reference after an account has authenticated. */
.teacher-login-page .tl-card:has(#empLoading:not([hidden])),
.teacher-login-page .tl-card:has(#empApproved:not([hidden])),
.teacher-login-page .tl-card:has(#empPending:not([hidden])) {
  inset: 5.3% 7.8% 5.5% 51.2%;
  width: auto;
  height: auto;
  padding: 7%;
  border: 1px solid rgba(178, 236, 215, .38);
  border-radius: 38px;
  background: rgba(2, 20, 20, .88);
  box-shadow: 0 20px 80px rgba(0, 0, 0, .28), inset 0 1px 0 rgba(255, 255, 255, .08);
  backdrop-filter: blur(10px);
}
.teacher-login-page .tl-card:has(#empLoading:not([hidden])) .tl-state,
.teacher-login-page .tl-card:has(#empApproved:not([hidden])) .tl-state,
.teacher-login-page .tl-card:has(#empPending:not([hidden])) .tl-state { text-align: center; }
.teacher-login-page .tl-card:has(#empLoading:not([hidden])) .tl-h1,
.teacher-login-page .tl-card:has(#empApproved:not([hidden])) .tl-h1,
.teacher-login-page .tl-card:has(#empPending:not([hidden])) .tl-h1 { color: #f8fafc; }
.teacher-login-page .tl-card:has(#empLoading:not([hidden])) .tl-sub,
.teacher-login-page .tl-card:has(#empApproved:not([hidden])) .tl-sub,
.teacher-login-page .tl-card:has(#empPending:not([hidden])) .tl-sub { color: #c7d1d0; }

@media (max-width: 900px) {
  .teacher-login-page { display: block; overflow: auto; }
  .teacher-login-page .tl-main {
    display: grid;
    width: 100%;
    height: auto;
    min-height: 100svh;
    margin: 0;
    padding: 28px 20px 88px;
    background: linear-gradient(145deg, #031a19, #020d0d);
  }
  .teacher-login-page .tl-student-portal {
    top: auto;
    left: 20px;
    bottom: 20px;
    padding: 10px 13px;
    font-size: .82rem;
  }
  .teacher-login-page .tl-card,
  .teacher-login-page .tl-card:has(#empLoading:not([hidden])),
  .teacher-login-page .tl-card:has(#empApproved:not([hidden])),
  .teacher-login-page .tl-card:has(#empPending:not([hidden])) {
    position: relative;
    inset: auto;
    width: min(100%, 560px);
    height: auto;
    margin: auto;
    padding: 34px 26px;
    border: 1px solid rgba(178, 236, 215, .3);
    border-radius: 26px;
    background: rgba(2, 20, 20, .92);
    box-shadow: 0 20px 60px rgba(0, 0, 0, .32);
  }
  .teacher-login-page #empSignedOut { display: flex; flex-direction: column; }
  .teacher-login-page #empSignedOut .tl-h1,
  .teacher-login-page #empSignedOut .tl-login-form label,
  .teacher-login-page #empSignedOut .tl-or,
  .teacher-login-page #empSignedOut .tl-trust {
    position: static;
    width: auto;
    height: auto;
    margin: 0;
    overflow: visible;
    clip: auto;
    clip-path: none;
    white-space: normal;
  }
  .teacher-login-page #empSignedOut .tl-h1 { color: #f8fafc; font-size: 2rem; text-align: center; }
  .teacher-login-page #empSignedOut .tl-login-form { position: static; display: flex; flex-direction: column; margin-top: 28px; }
  .teacher-login-page #empSignedOut .tl-login-form label { margin: 0 0 9px; color: #f8fafc; font-size: .92rem; font-weight: 600; }
  .teacher-login-page #empSignedOut .tl-login-form input {
    position: static;
    width: 100%;
    height: 54px;
    margin: 0 0 22px;
    padding: 0 16px;
    border: 1px solid rgba(180, 224, 222, .24);
    border-radius: 10px;
    background: rgba(1, 19, 20, .62);
    color: #f8fafc;
    font-size: 1rem;
  }
  .teacher-login-page #empSignedOut .tl-login-form input::placeholder { color: #9aa8a8; }
  .teacher-login-page #empSignedOut .tl-login-form input:not(:placeholder-shown) { background: rgba(1, 19, 20, .9); }
  .teacher-login-page .tl-password-wrap { position: relative; }
  .teacher-login-page #empPassword { padding-right: 50px; margin-bottom: 0; }
  .teacher-login-page .tl-password-wrap button { top: 0; right: 0; left: auto; width: 50px; height: 54px; color: #f8fafc; }
  .teacher-login-page .tl-forgot { position: static; align-self: flex-end; width: auto; height: auto; margin-top: 16px; color: #a7e4ba; font-size: .9rem; }
  .teacher-login-page .tl-login-form .tl-primary { position: static; width: 100%; height: auto; margin-top: 24px; padding: 15px 20px; border-radius: 10px; background: #a7e4ba; color: #06201a; font-size: 1rem; font-weight: 700; }
  .teacher-login-page .tl-google { position: static; display: flex; align-items: center; justify-content: center; gap: 12px; width: 100%; height: auto; margin-top: 0; padding: 15px 20px; border: 1px solid rgba(180, 224, 222, .34); border-radius: 10px; background: rgba(1, 18, 19, .45); color: #f8fafc; font-size: 1rem; font-weight: 600; }
  .teacher-login-page .tl-google svg { display: block; width: 21px; height: 21px; }
  .teacher-login-page #empSignedOut .tl-or { display: flex; align-items: center; gap: 14px; margin: 24px 0; color: #c4cecd; }
  .teacher-login-page #empSignedOut .tl-or::before, .teacher-login-page #empSignedOut .tl-or::after { content: ""; flex: 1; height: 1px; background: rgba(180, 224, 222, .2); }
  .teacher-login-page #empSignedOut .tl-trust { display: inline-flex; align-items: center; justify-content: center; gap: 9px; margin: 26px auto 0; color: #c7d1d0; font-size: .88rem; }
  .teacher-login-page #empSignedOut .tl-trust svg { width: 19px; height: 19px; color: #a7e4ba; }
  .teacher-login-page .google-note:not([hidden]) { position: static; width: auto; margin-top: 10px; font-size: .86rem; }
}
/* =========================================================
   The question library — admin console only (.lb-*)

   A browse-and-correct surface, not a marketing page: dense, two-column,
   and it has to render a question the way a student will see it, because
   that is the only way a wrong extraction is spotted before it ships.
   ========================================================= */

.lb-wrap {
  display: grid;
  grid-template-columns: 260px minmax(0, 1fr);
  gap: 24px;
  align-items: start;
}

/* ---- left: exam → subject → chapter ---- */

.lb-nav {
  position: sticky;
  top: calc(var(--header-h) + 16px);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 14px;
  background: #fff;
  max-height: calc(100dvh - var(--header-h) - 48px);
  overflow-y: auto;
}
.lb-navhead {
  margin: 0 0 10px;
  font-size: .8rem;
  color: var(--muted);
}
.lb-exam h4 {
  margin: 12px 0 4px;
  font-size: .78rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--muted);
}
.lb-subject {
  margin: 8px 0 2px;
  font-size: .82rem;
  font-weight: 600;
  color: var(--text);
}
.lb-nav ul { list-style: none; margin: 0; padding: 0; }
.lb-chapter {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 7px 8px;
  border: 0;
  border-radius: 8px;
  background: none;
  font: inherit;
  font-size: .88rem;
  text-align: left;
  color: var(--text);
  cursor: pointer;
}
.lb-chapter:hover { background: var(--bg-soft); }
.lb-chapter.active { background: var(--primary-light); color: var(--primary-dark); font-weight: 600; }
.lb-chip {
  flex: none;
  font-size: .72rem;
  padding: 1px 7px;
  border-radius: 999px;
  background: var(--bg-soft);
  color: var(--muted);
}
.lb-chip.done { background: #e5f7ee; color: var(--q-answered); }

/* =========================================================================
   LIBRARY — screen 1 (exam cards) and the browse chrome
   =========================================================================

   ONE accent token, resolved per panel. The console is blue; the teacher panel
   is deep green and scopes its own `--tp-green*` rather than overriding
   `--primary` (a bare override would repaint 52 marketing pages — §19). The
   picker is shared by both, so hardcoding either colour would be wrong in one
   of them. This is the whole of the difference. */
.lb-home, .lb-browse {
  --lb-accent: var(--primary);
  --lb-accent-soft: var(--primary-light);
  --lb-accent-line: var(--primary);
}
.tp-panel .lb-home, .tp-panel .lb-browse {
  --lb-accent: var(--tp-green);
  --lb-accent-soft: var(--tp-green-soft);
  --lb-accent-line: var(--tp-green-line);
}

.lb-home-head { margin-bottom: 16px; }

/* ---- find a chapter ---- */

.lb-findwrap { margin-bottom: 8px; }
.lb-findinput,
.lb-searchinput {
  width: 100%;
  padding: 10px 14px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: #fff;
  font: inherit;
  font-size: .9rem;
  color: var(--text);
}
.lb-findinput::placeholder,
.lb-searchinput::placeholder { color: var(--muted); }
.lb-findinput:focus,
.lb-searchinput:focus {
  outline: none;
  border-color: var(--lb-accent);
  box-shadow: 0 0 0 3px var(--lb-accent-soft);
}

.lb-findlist {
  border: 1px solid var(--border);
  border-radius: 12px;
  background: #fff;
  padding: 6px;
  margin-bottom: 18px;
  max-height: 320px;
  overflow-y: auto;
}
.lb-find {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 8px 10px;
  border: 0;
  border-radius: 8px;
  background: none;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.lb-find:hover { background: var(--bg-soft); }
.lb-find-name { font-size: .9rem; font-weight: 600; color: var(--text); }
.lb-find-where { flex: 1; font-size: .78rem; color: var(--muted); }

/* ---- the exam cards ---- */

.lb-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 14px;
}
.lb-card {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 18px;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: #fff;
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: border-color .15s, box-shadow .15s, transform .15s;
}
.lb-card:hover {
  border-color: var(--lb-accent);
  box-shadow: var(--shadow);
  transform: translateY(-2px);
}
.lb-card-name {
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--lb-accent);
  letter-spacing: .01em;
}
.lb-card-count { font-size: .92rem; font-weight: 600; color: var(--text); }
.lb-card-subs { font-size: .82rem; color: var(--muted); line-height: 1.5; }
.lb-card-foot {
  margin-top: 6px;
  padding-top: 8px;
  border-top: 1px solid var(--border);
  font-size: .76rem;
  color: var(--muted);
}

/* ---- browse chrome: back + exam chips ---- */

.lb-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 16px;
  margin-bottom: 16px;
}
.lb-back {
  flex: none;
  border: 0;
  background: none;
  font: inherit;
  font-size: .88rem;
  font-weight: 600;
  color: var(--lb-accent);
  cursor: pointer;
  padding: 4px 0;
}
.lb-back:hover { text-decoration: underline; }

.lb-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.lb-examchip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px 13px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: #fff;
  font: inherit;
  font-size: .84rem;
  color: var(--text);
  cursor: pointer;
}
.lb-examchip span {
  font-size: .72rem;
  color: var(--muted);
}
.lb-examchip:hover { border-color: var(--lb-accent); }
.lb-examchip.active {
  background: var(--lb-accent);
  border-color: var(--lb-accent);
  color: #fff;
  font-weight: 600;
}
.lb-examchip.active span { color: rgba(255, 255, 255, .8); }

/* ---- left nav: subject accordion ---- */

.lb-subj + .lb-subj { margin-top: 2px; }
.lb-subjbtn {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 8px;
  border: 0;
  border-radius: 8px;
  background: none;
  font: inherit;
  font-size: .86rem;
  font-weight: 600;
  color: var(--text);
  text-align: left;
  cursor: pointer;
}
.lb-subjbtn:hover { background: var(--bg-soft); }
.lb-subjname { flex: 1; }
.lb-caret {
  flex: none;
  width: 0;
  height: 0;
  border-left: 5px solid var(--muted);
  border-top: 4px solid transparent;
  border-bottom: 4px solid transparent;
  transition: transform .15s;
}
.lb-subj.open .lb-caret { transform: rotate(90deg) translateX(1px); }
.lb-subj.open > .lb-subjbtn { color: var(--lb-accent); }
.lb-subj ul { margin: 2px 0 2px 10px; padding-left: 8px; border-left: 1px solid var(--border); }

.lb-more {
  display: block;
  margin: 2px 0 6px 18px;
  border: 0;
  background: none;
  font: inherit;
  font-size: .78rem;
  font-weight: 600;
  color: var(--lb-accent);
  cursor: pointer;
  padding: 4px 0;
}
.lb-more:hover { text-decoration: underline; }

/* ---- toolbar search + the per-row Add ---- */

.lb-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.lb-search { flex: 1 1 220px; min-width: 180px; max-width: 340px; }

.lb-add { flex: none; }
.lb-add:not(.is-on) {
  background: var(--lb-accent);
  border-color: var(--lb-accent);
  color: #fff;
}
.lb-add:not(.is-on):hover { filter: brightness(.93); }
.lb-add.is-on {
  background: var(--lb-accent-soft);
  border: 1px solid var(--lb-accent);
  color: var(--lb-accent);
  font-weight: 600;
}

@media (max-width: 720px) {
  .lb-cards { grid-template-columns: 1fr; }
  .lb-search { max-width: none; }
}

/* ---- right: the questions ---- */

.lb-head {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: flex-end;
  gap: 12px;
  margin-bottom: 14px;
}
.lb-title { margin: 0; font-size: 1.25rem; text-transform: capitalize; }
.lb-sub { margin: 2px 0 0; color: var(--muted); font-size: .88rem; }

/* Shown only when the server capped the chapter list. Deliberately the same
   treatment as .ad-warnbox — a cap the owner cannot see reads as a complete
   chapter, which is how questions get uploaded and never picked. */
.lb-truncated {
  background: #fff6ed;
  border: 1px solid #f6d9bd;
  border-left: 3px solid var(--accent);
  border-radius: 0 12px 12px 0;
  padding: 12px 16px;
  margin: 0 0 14px;
  font-size: .86rem;
  line-height: 1.6;
  color: var(--text);
}

.lb-actionbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px;
  padding: 10px 14px;
  margin-bottom: 14px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--bg-soft);
}
.lb-selall { display: flex; align-items: center; gap: 7px; font-size: .88rem; cursor: pointer; }
.lb-selnote { color: var(--muted); font-size: .85rem; margin-right: auto; }

.lb-q {
  display: grid;
  grid-template-columns: 28px minmax(0, 1fr);
  gap: 10px;
  padding: 16px;
  margin-bottom: 12px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: #fff;
}
.lb-q.picked { border-color: var(--primary); box-shadow: 0 0 0 1px var(--primary) inset; }
.lb-pick { padding-top: 2px; }

.lb-qmeta {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  margin-bottom: 8px;
  font-size: .74rem;
  color: var(--muted);
}
.lb-qmeta > span { padding: 1px 7px; border-radius: 999px; background: var(--bg-soft); }
.lb-type { text-transform: capitalize; }
.lb-ok   { background: #e5f7ee !important; color: var(--q-answered); }
.lb-new  { background: var(--tint-peach) !important; color: var(--accent-deep); }
.lb-used { background: var(--tint-blue) !important; color: var(--primary-dark); }
.lb-flag { background: #fde8ea !important; color: var(--q-not-answered); }

.lb-qbody { line-height: 1.6; }
.lb-qfig { max-width: 100%; height: auto; margin: 10px 0; border-radius: 8px; }

.lb-opts {
  list-style: none;
  margin: 10px 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 6px 16px;
}
.lb-opt {
  display: flex;
  gap: 8px;
  font-size: .92rem;
  padding: 4px 0;
}
/* The option letter is drawn, never stored — the ids are deliberately
   non-positional so nothing in the data reveals which answer is which. */
.lb-opt { counter-increment: lbopt; }
.lb-opts { counter-reset: lbopt; }
.lb-opt::before {
  content: counter(lbopt, upper-alpha) ".";
  flex: none;
  color: var(--muted);
  font-weight: 600;
}
.lb-optbody img { max-width: 180px; height: auto; vertical-align: middle; }

.lb-qacts { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }

.lb-answer {
  margin-top: 12px;
  padding: 12px 14px;
  border-radius: 10px;
  background: var(--bg-soft);
  font-size: .92rem;
}
.lb-solimg { max-width: 100%; height: auto; display: block; margin: 8px 0; border-radius: 8px; }

/* ---- dialogs ---- */

.lb-modal {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: rgba(20, 25, 43, .55);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 24px 16px;
  overflow-y: auto;
}
.lb-dialog {
  width: min(760px, 100%);
  background: #fff;
  border-radius: 14px;
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}
.lb-dialog-head,
.lb-dialog-foot {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 18px;
}
.lb-dialog-head { border-bottom: 1px solid var(--border); }
.lb-dialog-head h3 { margin: 0; font-size: 1.05rem; margin-right: auto; }
.lb-dialog-foot { border-top: 1px solid var(--border); justify-content: flex-end; }
.lb-dialog-foot .lb-err { margin: 0 auto 0 0; }
.lb-dialog-body { padding: 18px; }
.lb-x {
  border: 0; background: none; cursor: pointer;
  font-size: 1.5rem; line-height: 1; color: var(--muted);
}

.lb-field { display: block; margin-bottom: 6px; font-size: .85rem; font-weight: 600; }
.lb-field textarea,
.lb-opttext {
  width: 100%;
  margin-top: 4px;
  padding: 9px 11px;
  border: 1px solid var(--border);
  border-radius: 8px;
  font: inherit;
  font-weight: 400;
}
.lb-fieldlabel { margin: 16px 0 6px; font-size: .85rem; font-weight: 600; }
.lb-hint { margin: 6px 0; font-size: .8rem; color: var(--muted); }
.lb-note { margin: 14px 0 0; font-size: .84rem; color: var(--muted); line-height: 1.55; }
.lb-err { color: var(--q-not-answered); font-size: .86rem; }

/* What the student will see, live as you type. The point of the panel. */
.lb-preview {
  min-height: 44px;
  padding: 11px 13px;
  border: 1px dashed var(--border);
  border-radius: 8px;
  background: var(--bg-soft);
  line-height: 1.6;
}

.lb-editopts { list-style: none; margin: 0; padding: 0; }
.lb-editopts li { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.lb-editopts img { max-width: 120px; height: auto; }
.lb-optpick { display: flex; align-items: center; gap: 5px; font-weight: 600; }

.lb-form {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 12px;
  margin-top: 12px;
}
.lb-form label { font-size: .85rem; font-weight: 600; }
.lb-form input,
.lb-form select {
  width: 100%;
  margin-top: 4px;
  padding: 9px 11px;
  border: 1px solid var(--border);
  border-radius: 8px;
  font: inherit;
  font-weight: 400;
}

@media (max-width: 900px) {
  .lb-wrap { grid-template-columns: 1fr; }
  .lb-nav { position: static; max-height: none; }
}

/* =========================================================
   STUDENT SIGN-IN (.ss-*)
   Google-only entrance. The supplied student artwork is used as-is and the
   page deliberately has no site chrome or bottom/footer bar.
   ========================================================= */
.student-auth-body {
  margin: 0;
  min-width: 0;
  background: #f8faff;
  color: #10204b;
  font-family: Poppins, sans-serif;
}
.student-auth-page { min-height: 100svh; }
.student-auth-split {
  display: grid;
  grid-template-columns: minmax(0, 1.0833fr) minmax(0, 1fr);
  min-height: 100svh;
}

/* ---------- promotional panel ---------- */
.ss-promo {
  position: relative;
  isolation: isolate;
  display: flex;
  flex-direction: column;
  min-height: 100svh;
  overflow: hidden;
  padding: clamp(42px, 5vw, 82px) clamp(34px, 4.4vw, 72px) clamp(38px, 4vw, 64px);
  background: linear-gradient(132deg, #061a45 0%, #092d87 52%, #0d47c7 100%);
  color: #fff;
}
.ss-promo::before {
  content: "";
  position: absolute;
  z-index: -1;
  width: min(48vw, 770px);
  height: min(48vw, 770px);
  right: -30%;
  top: -22%;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(56, 140, 255, .30), rgba(31, 100, 226, .08) 48%, transparent 70%);
}
.ss-orbit {
  position: absolute;
  z-index: -1;
  border: 1px solid rgba(150, 202, 255, .18);
  border-radius: 50%;
  pointer-events: none;
}
.ss-orbit-one { width: min(48vw, 730px); height: min(48vw, 730px); right: -21%; top: 3%; }
.ss-orbit-two { width: min(37vw, 560px); height: min(37vw, 560px); right: -13%; top: 11%; border-color: rgba(150, 202, 255, .13); }
.ss-dots {
  position: absolute;
  z-index: -1;
  width: 148px;
  height: 172px;
  right: 5%;
  bottom: 7%;
  opacity: .42;
  background-image: radial-gradient(rgba(131, 195, 255, .82) 1.1px, transparent 1.3px);
  background-size: 12px 12px;
  mask-image: linear-gradient(135deg, transparent, #000 24%, #000 72%, transparent);
}
.ss-promo-copy {
  position: relative;
  z-index: 2;
  width: min(100%, 470px);
  margin-top: clamp(14px, 4vh, 62px);
}
.ss-admissions {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin: 0 0 27px;
  padding: 9px 16px;
  border: 1px solid rgba(137, 193, 255, .38);
  border-radius: 999px;
  background: rgba(4, 32, 96, .46);
  color: #e9f4ff;
  font-size: clamp(.8rem, 1.05vw, 1rem);
  font-weight: 700;
  letter-spacing: .055em;
  line-height: 1.1;
  text-transform: uppercase;
}
.ss-admissions span { color: #5ca8ff; }
.ss-promo h1 {
  margin: 0;
  max-width: 100%;
  color: #fff;
  font-size: clamp(1.5rem, 2.3vw, 2.5rem);
  font-weight: 400;
  letter-spacing: -0.02em;
  line-height: 1.28;
}
.ss-promo h1 span { color: #53a0ff; }
.ss-promo-sub {
  max-width: 32ch;
  margin: 23px 0 0;
  color: rgba(255, 255, 255, .77);
  font-size: clamp(.91rem, 1.14vw, 1.08rem);
  line-height: 1.75;
}
.ss-student-art {
  position: absolute;
  z-index: 1;
  right: -5%;
  bottom: 35%;
  width: min(66%, 690px);
  pointer-events: none;
}
.ss-student-glow {
  position: absolute;
  z-index: -1;
  right: 6%;
  bottom: 12%;
  width: 78%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(104, 183, 255, .44), rgba(45, 119, 244, .20) 42%, transparent 70%);
  filter: blur(8px);
}
.ss-student-art img {
  display: block;
  width: 100%;
  height: auto;
  max-height: 75svh;
  object-fit: contain;
  object-position: right bottom;
  filter: grayscale(1) sepia(.45) saturate(6) hue-rotate(168deg) brightness(.72) contrast(1.1);
  opacity: .82;
}
.ss-feature-grid {
  position: relative;
  z-index: 3;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(9px, 1.2vw, 18px);
  margin-top: auto;
  padding-top: 28px;
}
.ss-feature-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  min-height: 118px;
  padding: 17px 16px;
  border: 1px solid rgba(105, 172, 255, .33);
  border-radius: 15px;
  background: rgba(4, 34, 105, .86);
  box-shadow: 0 10px 28px rgba(0, 13, 53, .12);
}
.ss-feature-card svg { width: 25px; height: 25px; margin-bottom: 12px; color: #4a9aff; }
.ss-feature-card strong { color: #fff; font-size: clamp(.86rem, 1.05vw, 1.05rem); font-weight: 700; line-height: 1.25; }

/* ---------- Google-only access panel ---------- */
.ss-auth-panel {
  display: grid;
  min-width: 0;
  min-height: 100svh;
  place-items: center;
  padding: 48px clamp(28px, 5vw, 86px);
  background: #fbfcff;
}
.ss-auth-inner { width: min(100%, 500px); }
.ss-auth-inner h2 {
  margin: 0;
  color: #10204b;
  font-size: clamp(2rem, 3.1vw, 2.75rem);
  font-weight: 700;
  letter-spacing: -.05em;
  line-height: 1.1;
}
.ss-auth-sub {
  margin: 14px 0 34px;
  color: #64708a;
  font-size: .98rem;
  line-height: 1.65;
}
.ss-google {
  position: relative;
  min-height: 60px;
  padding: 14px 56px;
  border: 1px solid #dbe1ec;
  border-radius: 14px;
  background: #fff;
  box-shadow: 0 4px 12px rgba(25, 47, 95, .04);
  color: #142143;
  font-size: 1rem;
  font-weight: 600;
}
.ss-google svg { position: absolute; left: 22px; width: 23px; height: 23px; }
.ss-google:hover { border-color: #9ebdfa; box-shadow: 0 8px 20px rgba(23, 72, 175, .12); transform: translateY(-1px); }
.ss-google:focus-visible { outline: 3px solid rgba(35, 134, 255, .34); outline-offset: 3px; }
.ss-google:disabled { cursor: wait; opacity: .68; transform: none; }
.ss-google-note { margin: 12px 0 0; color: #bf3a4a; font-size: .8rem; line-height: 1.45; text-align: center; }

/* ---------- email + password, OTP-verified once at signup ---------- */
.ss-divider {
  display: flex;
  align-items: center;
  gap: 14px;
  margin: 26px 0;
  color: #9aa5bd;
  font-size: .78rem;
  text-transform: uppercase;
  letter-spacing: .06em;
}
.ss-divider::before, .ss-divider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: #e5e9f1;
}
.ss-email-tabs {
  display: flex;
  gap: 4px;
  margin-bottom: 18px;
  padding: 4px;
  border-radius: 12px;
  background: #f1f4fa;
}
.ss-email-tab {
  flex: 1;
  padding: 10px 12px;
  border: 0;
  border-radius: 9px;
  background: transparent;
  color: #56627a;
  font-size: .84rem;
  font-weight: 600;
  cursor: pointer;
  transition: background .2s ease, color .2s ease, box-shadow .2s ease;
}
.ss-email-tab.active { background: #fff; color: #10204b; box-shadow: 0 2px 8px rgba(25, 47, 95, .08); }
.ss-email-tab:focus-visible { outline: 3px solid rgba(35, 134, 255, .34); outline-offset: 2px; }

.ss-email-form { display: flex; flex-direction: column; gap: 12px; }
.ss-email-form label { color: #10204b; font-size: .82rem; font-weight: 600; }
.ss-email-form input {
  width: 100%;
  min-height: 48px;
  padding: 10px 14px;
  border: 1px solid #dbe1ec;
  border-radius: 12px;
  background: #fff;
  color: #10204b;
  font-size: .95rem;
}
.ss-email-form input:focus-visible { outline: 3px solid rgba(35, 134, 255, .34); outline-offset: 1px; border-color: #9ebdfa; }
.ss-email-form input#suCode { letter-spacing: .3em; text-align: center; font-weight: 700; }
.ss-email-form .btn { width: 100%; min-height: 48px; margin-top: 4px; }
.ss-email-form .google-note { margin-top: 4px; }
.ss-link-btn {
  align-self: flex-start;
  padding: 4px 0;
  border: 0;
  background: none;
  color: #1658d8;
  font-size: .8rem;
  font-weight: 600;
  cursor: pointer;
}
.ss-link-btn:hover, .ss-link-btn:focus-visible { color: #0d47c7; text-decoration: underline; text-underline-offset: 2px; }
.ss-link-btn:disabled { color: #9aa5bd; cursor: default; text-decoration: none; }

.ss-consent {
  max-width: 42ch;
  margin: 18px auto 0;
  color: #7a8498;
  font-size: .76rem;
  line-height: 1.65;
  text-align: center;
}
.ss-consent a { color: #1658d8; font-weight: 600; text-decoration: none; }
.ss-consent a:hover, .ss-consent a:focus-visible { color: #0d47c7; text-decoration: underline; text-underline-offset: 2px; }
.ss-employee-access {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  margin-top: 38px;
  padding-top: 28px;
  border-top: 1px solid #e5e9f1;
}
.ss-employee-access p { margin: 0; color: #56627a; font-size: .85rem; }
.ss-employee-link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 42px;
  padding: 9px 13px;
  border: 1px solid #dbe3f1;
  border-radius: 10px;
  color: #174fb9;
  font-size: .82rem;
  font-weight: 600;
  text-decoration: none;
  transition: border-color .2s ease, background .2s ease, box-shadow .2s ease;
}
.ss-employee-link svg { width: 17px; height: 17px; }
.ss-employee-link > span { font-size: 1.1rem; line-height: 1; }
.ss-employee-link:hover, .ss-employee-link:focus-visible { border-color: #91b9fa; background: #f4f8ff; box-shadow: 0 4px 12px rgba(30, 83, 185, .08); }
.ss-auth-success { text-align: center; }
.ss-auth-success .as-icon { display: grid; width: 56px; height: 56px; margin: 0 auto 18px; place-items: center; border-radius: 50%; background: #e7f8ed; color: #147344; font-size: 1.65rem; font-weight: 800; }
.ss-auth-success p { margin: 14px 0 28px; color: #64708a; }

@media (min-width: 901px) and (max-width: 1180px) {
  .ss-promo { padding-inline: 38px; }
  .ss-promo h1 { font-size: clamp(1.6rem, 5vw, 2.2rem); }
  .ss-student-art { right: -18%; width: 76%; bottom: 16%; }
  .ss-feature-grid { grid-template-columns: 1fr 1fr; max-width: 420px; }
  .ss-feature-card { min-height: 105px; }
  .ss-feature-card svg { margin-bottom: 14px; }
}

@media (max-width: 900px) {
  .student-auth-split { grid-template-columns: 1fr; min-height: 0; }
  .ss-auth-panel { order: -1; min-height: 0; padding: 52px 24px 44px; }
  .ss-auth-inner { width: min(100%, 500px); }
  .ss-promo { min-height: 720px; padding: 48px 24px 32px; }
  .ss-promo-copy { margin-top: 0; max-width: 440px; }
  .ss-promo h1 { font-size: clamp(1.5rem, 7vw, 2.15rem); }
  .ss-promo-sub { max-width: 34ch; }
  .ss-orbit-one { width: 640px; height: 640px; right: -34%; top: 0; }
  .ss-orbit-two { display: none; }
  .ss-student-art { right: -17%; bottom: 126px; width: min(76%, 550px); }
  .ss-feature-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; padding-top: 20px; }
  .ss-feature-card { min-height: 118px; padding: 14px; }
  .ss-feature-card svg { margin-bottom: 12px; }
}

@media (max-width: 480px) {
  .ss-auth-panel { padding: 44px 20px 38px; }
  .ss-auth-inner h2 { font-size: 2rem; }
  .ss-auth-sub { margin-bottom: 28px; font-size: .92rem; }
  .ss-google { min-height: 58px; padding-inline: 48px; font-size: .94rem; }
  .ss-google svg { left: 18px; width: 21px; height: 21px; }
  .ss-employee-access { align-items: flex-start; flex-direction: column; gap: 14px; margin-top: 30px; padding-top: 24px; }
  .ss-employee-link { width: 100%; justify-content: center; }
  .ss-promo { min-height: 690px; padding: 40px 20px 24px; }
  .ss-admissions { margin-bottom: 21px; }
  .ss-student-art { right: -28%; bottom: 126px; width: 96%; }
  .ss-feature-card strong { font-size: .94rem; }
  .ss-feature-card span { font-size: .67rem; }
  .ss-dots { display: none; }
}

/* Was nested inside the old resources block but is NOT resources-specific —
   it trims the SITE header gutter on every page under 760px. Kept out here
   when that block was replaced 17 Aug 2026 so the swap did not silently
   change mobile header padding sitewide. */
@media (max-width: 760px) {
  .site-header .header-inner { padding-inline: 18px; }
}

/* =========================================================================
   RESOURCES / SYLLABUS  (.rs-*)  — rebuilt 17 Aug 2026 from
   design-drafts/resources-v2-cards.html ("exam gallery"), chosen by the owner
   out of three drafts.

   Replaces the old .syllabus-* / .exam-picker / .exam-option left-rail page.

   ⚠ EVERY CLASS HERE IS rs- PREFIXED ON PURPOSE. The draft was a standalone
   file, so it used bare names — and those names are already load-bearing on
   this site. Counted in public/ at the time of the port: `.section` on 90
   elements, `.num` 76, `.hero` 32, `.arrow` 26, `.panel` 23, `.rail` 16,
   `.count` 8, `.chips` 4, plus `.btn` (56 pages), `.brand` (54),
   `.site-header` / `.main-nav` / `.nav-toggle` (52 each). Pasting the draft's
   stylesheet in unprefixed would have restyled every one of them.
   Keep the prefix on anything added here.

   The draft's own :root lives on .rs-page below rather than :root, for the
   same reason — `--brand`, `--soft`, `--display` etc. are draft vocabulary and
   must not leak into the site's token set. Site chrome (header, .btn,
   .container) is NOT redefined here: the page uses the real ones.
   ========================================================================= */
.rs-page{
  --brand:#1a2ef0;
  --brand-dark:#0f1ea8;
  --brand-tint:#eaecfe;
  --ink:#15161a;
  --body:#1f2430;
  --soft:#f6f8fd;
  --orange:#ff7a1a;
  --yellow:#ffb703;
  --shadow-sm:0 2px 8px rgba(20,25,43,.06);
  --shadow-lg:0 18px 44px rgba(20,25,43,.14);
  --r-sm:10px;
  --r:14px;
  --r-lg:18px;
  --display:"Barlow Condensed","Poppins",system-ui,sans-serif;
  --sans:"Poppins",system-ui,-apple-system,"Segoe UI",sans-serif;

  background:var(--soft);
  color:var(--body);
  font-family:var(--sans);
  font-size:15px;
  line-height:1.6;
}
/* the draft reset these globally; scoped so the rest of the site is untouched */
.rs-page h1,.rs-page h2,.rs-page h3,.rs-page h4{ margin:0; color:var(--ink); }
.rs-page p{ margin:0; }
.rs-page button{ font:inherit; color:inherit; }
.rs-page :focus-visible{ outline:3px solid var(--brand); outline-offset:2px; border-radius:6px; }

/* ---------- hero ---------- */
.rs-hero{
  position:relative;
  overflow:hidden;
  background:
    radial-gradient(900px 320px at 88% -30%, rgba(255,122,26,.16), transparent 60%),
    radial-gradient(760px 300px at 6% -10%, rgba(26,46,240,.16), transparent 62%),
    linear-gradient(180deg,#fff, var(--soft));
  border-bottom:1px solid var(--border);
  padding:38px 0 34px;
}
.rs-kicker{
  display:inline-flex;
  align-items:center;
  gap:7px;
  font-size:11.5px;
  font-weight:700;
  letter-spacing:.14em;
  text-transform:uppercase;
  color:var(--brand-dark);
  background:var(--brand-tint);
  border-radius:99px;
  padding:5px 12px;
}
.rs-hero h1{
  font-family:var(--display);
  font-weight:800;
  font-size:clamp(34px, 7vw, 60px);
  line-height:1.02;
  letter-spacing:.005em;
  margin:14px 0 0;
}
/* `isolation:isolate` is load-bearing, not decoration. The ::after highlighter
   below sits at z-index:-1; without a stacking context on the em itself that
   negative layer escapes to the nearest ancestor context and paints BEHIND
   .rs-hero's opaque background gradient, so the yellow bar is invisible. */
.rs-hero h1 em{
  font-style:normal;
  color:var(--brand);
  position:relative;
  isolation:isolate;
}
.rs-hero h1 em::after{
  content:"";
  position:absolute;
  left:0; right:0; bottom:.06em;
  height:.14em;
  background:var(--yellow);
  opacity:.55;
  border-radius:99px;
  z-index:-1;
}
/* 12px read as touching the heading — the underline decoration under "whole
   syllabus" sits at bottom:.06em of its own line, so with the h1's tight
   line-height:1.02 there was barely a gap between that yellow bar and the
   paragraph below it.

   ⚠ `.rs-page .rs-hero-lead`, not `.rs-hero-lead` alone: `.rs-page p{margin:0}`
   above (the draft's global <p> reset, scoped to this page) is (0,1,1) against
   this rule's bare (0,1,0) — a single un-scoped class here LOSES to that reset
   regardless of source order, and margin-top silently computed to 0. */
.rs-page .rs-hero-lead{
  margin-top:22px;
  max-width:56ch;
  font-size:15.5px;
  color:var(--muted);
}
.rs-hero-stats{
  display:flex;
  flex-wrap:wrap;
  gap:10px;
  margin-top:20px;
  padding:0;
  list-style:none;
}
.rs-hero-stats li{
  background:#fff;
  border:1px solid var(--border);
  border-radius:99px;
  padding:7px 14px;
  font-size:13px;
  font-weight:500;
  color:var(--body);
  box-shadow:var(--shadow-sm);
}
.rs-hero-stats b{
  font-family:var(--display);
  font-size:18px;
  font-weight:700;
  color:var(--brand-dark);
  margin-right:5px;
}

/* ---------- search ---------- */
.rs-searchbar{
  position:relative;
  display:flex;
  align-items:center;
  margin-top:22px;
  max-width:520px;
  background:#fff;
  border:1.5px solid var(--border);
  border-radius:99px;
  box-shadow:var(--shadow-sm);
  transition:border-color .15s ease, box-shadow .15s ease;
}
.rs-searchbar:focus-within{
  border-color:var(--brand);
  box-shadow:0 0 0 4px rgba(26,46,240,.12);
}
.rs-searchbar svg{
  position:absolute;
  left:15px;
  width:18px; height:18px;
  color:var(--muted);
  pointer-events:none;
}
.rs-searchbar input{
  flex:1;
  min-width:0;
  border:0;
  background:transparent;
  font:inherit;
  font-size:14.5px;
  color:var(--body);
  padding:12px 12px 12px 42px;
  border-radius:99px;
}
.rs-searchbar[hidden]{ display:none; }
.rs-searchbar input:focus{ outline:none; }
/* #8b93a3 measured 3.09:1 on white — under the 4.5:1 floor, and this is the
   only text that explains what the box does. #6b7280 is 4.83:1. */
.rs-searchbar input::placeholder{ color:#6b7280; }
.rs-search-clear{
  border:0;
  background:transparent;
  color:var(--muted);
  cursor:pointer;
  font-size:13px;
  font-weight:600;
  padding:8px 15px 8px 6px;
  border-radius:99px;
}
.rs-search-clear:hover{ color:var(--brand-dark); }
.rs-search-clear[hidden]{ display:none; }

/* ---------- views ---------- */
.rs-view[hidden]{ display:none; }
.rs-view{ animation:viewIn .32s ease both; }
@keyframes viewIn{
  from{ opacity:0; transform:translateY(10px); }
  to{ opacity:1; transform:none; }
}

.rs-section{ padding:34px 0 64px; }

.rs-section-head{
  display:flex;
  flex-wrap:wrap;
  align-items:baseline;
  justify-content:space-between;
  gap:8px;
  margin-bottom:16px;
}
.rs-section-head h2{
  font-family:var(--display);
  font-size:26px;
  font-weight:700;
  letter-spacing:.01em;
}
.rs-result-note{ font-size:13px; color:var(--muted); }

/* ---------- exam gallery ---------- */
.rs-gallery{
  display:grid;
  grid-template-columns:repeat(auto-fill, minmax(258px,1fr));
  gap:18px;
  list-style:none;
  margin:0;
  padding:0;
}
.rs-gallery li{ min-width:0; display:flex; }
.rs-gallery li[hidden]{ display:none; }

.rs-exam-card{
  position:relative;
  flex:1;
  display:flex;
  flex-direction:column;
  gap:10px;
  text-align:left;
  width:100%;
  min-width:0;
  background:#fff;
  border:1px solid var(--border);
  border-radius:var(--r-lg);
  padding:20px 18px 18px;
  cursor:pointer;
  overflow:hidden;
  box-shadow:var(--shadow-sm);
  transition:transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
.rs-exam-card::before{
  content:"";
  position:absolute;
  inset:0 0 auto 0;
  height:5px;
  background:linear-gradient(90deg, var(--a), var(--a-ink));
  z-index:2;
}
.rs-exam-card::after{
  content:"";
  position:absolute;
  right:-46px; top:-46px;
  width:130px; height:130px;
  border-radius:50%;
  background:var(--a-soft);
  opacity:.75;
  transition:transform .3s ease;
  z-index:0;
}
.rs-exam-card > *{ position:relative; z-index:1; }
.rs-exam-card:hover{
  transform:translateY(-4px);
  box-shadow:var(--shadow-lg);
  border-color:var(--a);
}
.rs-exam-card:hover::after{ transform:scale(1.18); }

.rs-card-name{
  font-family:var(--display);
  font-size:27px;
  font-weight:700;
  line-height:1.06;
  letter-spacing:.01em;
}
.rs-card-meta{
  font-size:12.5px;
  font-weight:600;
  color:var(--a-ink);
  letter-spacing:.01em;
}
.rs-card-blurb{
  font-size:13.4px;
  color:var(--muted);
  line-height:1.55;
}
.rs-card-foot{
  margin-top:auto;
  padding-top:12px;
  border-top:1px dashed var(--border);
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:8px;
  font-size:13px;
  font-weight:600;
  color:var(--a-ink);
}
.rs-card-foot .rs-arrow{ transition:transform .18s ease; }
.rs-exam-card:hover .rs-card-foot .rs-arrow{ transform:translateX(4px); }

.rs-pill-soon{
  display:inline-flex;
  align-items:center;
  gap:6px;
  align-self:flex-start;
  background:#fff6e0;
  border:1px solid #f5d489;
  color:#7a4b00;
  font-size:11.5px;
  font-weight:700;
  letter-spacing:.05em;
  text-transform:uppercase;
  border-radius:99px;
  padding:4px 10px;
}
.rs-card-hits{
  display:inline-flex;
  align-self:flex-start;
  background:var(--brand-tint);
  color:var(--brand-dark);
  font-size:12px;
  font-weight:600;
  border-radius:99px;
  padding:3px 10px;
}
.rs-card-hits[hidden]{ display:none; }

.rs-exam-card.rs-is-empty{ background:linear-gradient(180deg,#fff,#fbfcff); }

.rs-empty-search{
  background:#fff;
  border:1px dashed var(--border);
  border-radius:var(--r);
  padding:34px 20px;
  text-align:center;
  color:var(--muted);
}
.rs-empty-search[hidden]{ display:none; }
.rs-empty-search strong{ display:block; color:var(--ink); font-size:16px; margin-bottom:4px; }

/* helper band */
.rs-band{
  margin-top:34px;
  background:linear-gradient(120deg, var(--brand-dark), var(--brand) 62%, #4557f5);
  color:#fff;
  border-radius:var(--r-lg);
  padding:26px 24px;
  display:flex;
  flex-wrap:wrap;
  align-items:center;
  justify-content:space-between;
  gap:16px;
  box-shadow:var(--shadow);
}
.rs-band h3{
  color:#fff;
  font-family:var(--display);
  font-size:26px;
  font-weight:700;
  line-height:1.15;
}
/* .94 not .86: at .86 this measured 4.40:1 against the light end of the band's
   gradient, which fails AA on that tail even though it passes over the rest. */
.rs-band p{ color:rgba(255,255,255,.94); font-size:14px; margin-top:4px; max-width:52ch; }
.rs-band .btn-primary{ background:#fff; color:var(--brand-dark); box-shadow:none; }
.rs-band .btn-primary:hover{ background:var(--yellow); color:#3d2a00; }
.rs-band :focus-visible{ outline-color:#fff; }

/* ---------- detail view ---------- */
.rs-detail-hero{
  background:linear-gradient(180deg, var(--a-soft), #fff 82%);
  border-bottom:1px solid var(--border);
  padding:18px 0 26px;
}
.rs-backbtn{
  display:inline-flex;
  align-items:center;
  gap:8px;
  background:#fff;
  border:1.5px solid var(--border);
  border-radius:99px;
  padding:7px 15px 7px 11px;
  font-size:13.5px;
  font-weight:600;
  color:var(--body);
  cursor:pointer;
  box-shadow:var(--shadow-sm);
}
.rs-backbtn:hover{ border-color:var(--a); color:var(--a-ink); }
.rs-backbtn svg{ width:16px; height:16px; }

.rs-detail-top{
  display:flex;
  flex-wrap:wrap;
  align-items:flex-end;
  justify-content:space-between;
  gap:18px;
  margin-top:18px;
}
.rs-detail-id{ display:flex; align-items:center; gap:14px; min-width:0; }
.rs-detail-icon{
  flex:none;
  width:58px; height:58px;
  border-radius:15px;
  background:#fff;
  color:var(--a-ink);
  display:grid; place-items:center;
  border:1px solid var(--border);
  border-color:color-mix(in srgb, var(--a) 30%, #fff);
  box-shadow:var(--shadow-sm);
}
.rs-detail-icon svg{ width:31px; height:31px; }
.rs-detail-tag{
  display:inline-block;
  font-size:11.5px;
  font-weight:700;
  letter-spacing:.13em;
  text-transform:uppercase;
  color:var(--a-ink);
}
.rs-detail-top h1{
  font-family:var(--display);
  font-size:clamp(30px,5.4vw,44px);
  font-weight:800;
  line-height:1.04;
  letter-spacing:.005em;
}
/* .rs-page .rs-detail-sub, not .rs-detail-sub: see the note on .rs-hero-lead
   above — a bare single-class rule on a <p> loses margin-top to the page's
   own `.rs-page p{margin:0}` reset regardless of source order. */
.rs-page .rs-detail-sub{ font-size:14px; color:var(--muted); margin-top:3px; }

.rs-chips{ display:flex; flex-wrap:wrap; gap:8px; list-style:none; margin:0; padding:0; }
.rs-chips li{
  background:#fff;
  border:1px solid var(--border);
  border-radius:99px;
  padding:6px 13px;
  font-size:12.5px;
  font-weight:500;
  box-shadow:var(--shadow-sm);
}
.rs-chips b{
  font-family:var(--display);
  font-size:17px;
  font-weight:700;
  color:var(--a-ink);
  margin-right:4px;
}

.rs-detail-body{
  display:grid;
  grid-template-columns:262px minmax(0,1fr);
  gap:22px;
  align-items:start;
  padding:26px 0 66px;
}

/* subject rail */
.rs-rail{
  position:sticky;
  top:86px;
  background:#fff;
  border:1px solid var(--border);
  border-radius:var(--r);
  padding:12px;
  box-shadow:var(--shadow-sm);
  min-width:0;
}
.rs-rail-title{
  font-size:11.5px;
  font-weight:700;
  letter-spacing:.13em;
  text-transform:uppercase;
  color:var(--muted);
  padding:4px 8px 10px;
}
.rs-rail-list{ display:flex; flex-direction:column; gap:4px; }
.rs-rail-btn{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:10px;
  width:100%;
  text-align:left;
  background:transparent;
  border:0;
  border-radius:var(--r-sm);
  padding:10px 11px;
  cursor:pointer;
  font-size:13.6px;
  font-weight:500;
  color:var(--body);
  line-height:1.35;
  transition:background .15s ease, color .15s ease;
}
.rs-rail-btn:hover{ background:var(--soft); }
.rs-rail-btn .rs-count{
  flex:none;
  font-size:11.5px;
  font-weight:700;
  color:var(--muted);
  background:var(--soft);
  border-radius:99px;
  padding:2px 8px;
}
.rs-rail-btn[aria-selected="true"]{
  background:var(--a-soft);
  color:var(--a-ink);
  font-weight:600;
  box-shadow:inset 3px 0 0 var(--a-ink);
}
.rs-rail-btn[aria-selected="true"] .rs-count{
  background:#fff;
  color:var(--a-ink);
}
.rs-rail-btn.rs-is-dim{ opacity:.45; }

/* topics panel */
.rs-panel{
  background:#fff;
  border:1px solid var(--border);
  border-radius:var(--r);
  padding:20px;
  box-shadow:var(--shadow-sm);
  min-width:0;
}
.rs-panel-head{
  display:flex;
  flex-wrap:wrap;
  align-items:center;
  justify-content:space-between;
  gap:10px;
  padding-bottom:14px;
  border-bottom:1px solid var(--border);
  margin-bottom:16px;
}
.rs-panel-head h2{
  font-family:var(--display);
  font-size:24px;
  font-weight:700;
  letter-spacing:.01em;
  line-height:1.15;
}
.rs-panel-count{
  font-size:12.5px;
  font-weight:600;
  color:var(--a-ink);
  background:var(--a-soft);
  border-radius:99px;
  padding:5px 12px;
  white-space:nowrap;
}

.rs-topics{
  display:grid;
  grid-template-columns:repeat(auto-fill, minmax(232px,1fr));
  gap:8px;
  list-style:none;
  margin:0;
  padding:0;
}
.rs-topics li{
  display:flex;
  align-items:flex-start;
  gap:10px;
  min-width:0;
  background:var(--soft);
  border:1px solid transparent;
  border-radius:var(--r-sm);
  padding:10px 12px;
  font-size:13.6px;
  line-height:1.45;
  overflow-wrap:anywhere;
  transition:background .14s ease, border-color .14s ease;
}
.rs-topics li:hover{ background:#fff; border-color:var(--a); }
.rs-topics .rs-num{
  flex:none;
  width:22px; height:22px;
  border-radius:7px;
  background:#fff;
  border:1px solid var(--border);
  color:var(--a-ink);
  font-size:11px;
  font-weight:700;
  display:grid;
  place-items:center;
  margin-top:1px;
}
mark{
  background:#fff2b8;
  color:var(--ink);
  border-radius:3px;
  padding:0 2px;
}

.rs-panel-nav{
  display:flex;
  flex-wrap:wrap;
  justify-content:space-between;
  gap:10px;
  margin-top:18px;
  padding-top:16px;
  border-top:1px solid var(--border);
}
.rs-navbtn{
  display:inline-flex;
  align-items:center;
  gap:7px;
  background:#fff;
  border:1.5px solid var(--border);
  border-radius:var(--r-sm);
  padding:9px 14px;
  font-size:13.2px;
  font-weight:600;
  color:var(--body);
  cursor:pointer;
  max-width:100%;
  min-width:0;
}
.rs-navbtn span{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; min-width:0; }
.rs-panel-nav .rs-navbtn{ flex:0 1 auto; }
.rs-navbtn:hover:not(:disabled){ border-color:var(--a); color:var(--a-ink); }
.rs-navbtn:disabled{ opacity:.4; cursor:not-allowed; }

/* search results mode */
.rs-rgroup{ margin-bottom:22px; }
.rs-rgroup:last-child{ margin-bottom:0; }
.rs-rgroup h3{
  font-size:13px;
  font-weight:700;
  letter-spacing:.06em;
  text-transform:uppercase;
  color:var(--a-ink);
  margin-bottom:9px;
}
.rs-no-hits{
  text-align:center;
  padding:30px 14px;
  color:var(--muted);
}
.rs-no-hits strong{ display:block; color:var(--ink); font-size:16px; margin-bottom:4px; }

/* empty exam state (Foundation) */
.rs-empty-exam{
  grid-column:1 / -1;
  background:#fff;
  border:1px solid var(--border);
  border-radius:var(--r-lg);
  box-shadow:var(--shadow-sm);
  padding:40px 24px;
  text-align:center;
  max-width:660px;
  margin:0 auto;
}
.rs-empty-art{
  width:96px; height:96px;
  margin:0 auto 18px;
  border-radius:50%;
  display:grid;
  place-items:center;
  background:var(--a-soft);
  color:var(--a-ink);
  border:1px solid var(--border);
  border-color:color-mix(in srgb, var(--a) 26%, #fff);
}
.rs-empty-art svg{ width:46px; height:46px; }
.rs-empty-exam h2{
  font-family:var(--display);
  font-size:30px;
  font-weight:700;
  line-height:1.12;
}
.rs-empty-exam p{
  color:var(--muted);
  font-size:14.5px;
  margin-top:10px;
  max-width:48ch;
  margin-inline:auto;
}
.rs-empty-status{
  display:inline-flex;
  align-items:center;
  gap:7px;
  background:#fff6e0;
  border:1px solid #f5d489;
  color:#7a4b00;
  font-size:12px;
  font-weight:700;
  letter-spacing:.06em;
  text-transform:uppercase;
  border-radius:99px;
  padding:5px 12px;
  margin-bottom:14px;
}
/* ⚠ THE ICON MUST BE SIZED HERE. This badge is built by JS as
   `<span class="rs-empty-status">` + an inline <svg> + text. Every other svg on
   the page is sized by its own wrapper rule; this one had none, so it fell
   through to the global `img,svg{max-width:100%}` and rendered at the SVG's
   intrinsic 100x100, blowing the badge up to 230x112px. The same bug sized a
   gallery "coming soon" pill at 184x89 and made the Foundation card 322px tall
   against 253px for every sibling. */
.rs-empty-status svg{ width:14px; height:14px; flex:none; }
.rs-empty-actions{
  display:flex;
  flex-wrap:wrap;
  gap:10px;
  justify-content:center;
  margin-top:22px;
}
/* .rs-page .rs-empty-note, not .rs-empty-note: same reset-vs-specificity issue
   as .rs-hero-lead above. */
.rs-page .rs-empty-note{
  margin-top:22px;
  padding-top:18px;
  border-top:1px dashed var(--border);
  font-size:12.8px;
  color:var(--muted);
}


/* ---------- responsive ---------- */
@media (max-width:1000px){
  .rs-detail-body{ grid-template-columns:minmax(0,1fr); }
  .rs-rail{
    position:static;
    padding:12px 12px 10px;
  }
  .rs-rail-list{
    flex-direction:row;
    flex-wrap:nowrap;
    overflow-x:auto;
    gap:8px;
    padding-bottom:6px;
    scrollbar-width:thin;
  }
  .rs-rail-btn{
    flex:none;
    width:auto;
    max-width:min(66vw, 330px);
    border:1px solid var(--border);
    border-radius:99px;
    padding:8px 12px;
    white-space:nowrap;
    font-size:13px;
  }
  /* a long subject name is truncated in the chip only — the panel
     heading below always shows it in full */
  .rs-rail-btn > span:first-child{
    overflow:hidden;
    text-overflow:ellipsis;
  }
  .rs-rail-btn[aria-selected="true"]{
    box-shadow:none;
    border-color:var(--a-ink);
  }
}


@media (max-width:560px){
  .rs-hero{ padding:26px 0 28px; }
  .rs-gallery{ grid-template-columns:1fr; gap:14px; }
  .rs-band{ padding:22px 18px; }
  .rs-panel{ padding:16px 14px; }
  .rs-detail-icon{ width:48px; height:48px; }
  .rs-detail-icon svg{ width:26px; height:26px; }
  .rs-topics{ grid-template-columns:1fr; }
  .rs-panel-nav .rs-navbtn{ flex:1 1 100%; justify-content:center; }
}


/* =========================================================================
   OWNER CONSOLE — Test series tab
   Teachers author; the owner publishes and prices. These are the controls
   that moved out of the teacher panel, plus the review queue that replaced
   "guess which draft is finished".
   ========================================================================= */

/* the papers waiting on the owner. Same treatment as .ad-warnbox because it is
   the same kind of thing: something that needs a person, not a notification. */
.ad-reviewbox #adReviewList { margin-top: 10px; display: grid; gap: 8px; }
.ad-reviewbox .ad-staff-row { border-color: #f0d9bd; }

/* a green tag, for the states that mean "this is out in the world" */
.ad-tag.ok { background: #e5f7ee; color: var(--q-answered); }

/* the pricing form drops onto its own line under the series it belongs to, so
   it can never be mistaken for the controls of the row below it */
.ad-series-row .ad-price-form { flex: 1 1 100%; }
.ad-price-form {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 10px;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px dashed var(--border);
}
.ad-price-form label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--muted);
}
.ad-price-form input[type="number"],
.ad-price-form input[type="text"] {
  border: 1px solid var(--border);
  border-radius: 9px;
  padding: 8px 10px;
  font: inherit;
  font-size: 0.85rem;
}
.ad-price-form input[type="number"] { width: 110px; }
.ad-price-form input[type="text"] { width: 240px; }
.ad-price-form .pf-msg { flex: 1 1 100%; margin: 0; }
.ad-check { flex-direction: row !important; align-items: center; gap: 7px !important; }

/* the code form carries five fields, so it wraps rather than squeezing */
.ad-code-row { flex-wrap: wrap; }
.ad-code-row input[type="number"] { width: 110px; }
.ad-code-row input[type="date"] { width: 165px; }
.ad-code-row .ad-select { min-width: 220px; }
.ad-code-row input[type="text"] { flex: 1 1 180px; }

/* a code is read out loud and copied by hand, so it is set in mono and spaced */
.ad-code {
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  background: var(--bg-soft);
  border: 1px solid var(--border);
  border-radius: 9px;
  padding: 7px 12px;
  color: var(--dark);
}

/* =========================================================================
   TEACHER PANEL — Draft / Sent for review / Live
   A teacher cannot publish, so they must be able to see where their paper
   actually is. One line, three states, never a guess.
   ========================================================================= */
.tp-status {
  border: 1px solid var(--border);
  border-left-width: 4px;
  border-radius: 10px;
  padding: 11px 14px;
  margin-bottom: 14px;
  font-size: 0.87rem;
  color: var(--muted);
  background: var(--bg-soft);
}
.tp-status strong { color: var(--text); }
.tp-status.is-draft { border-left-color: var(--q-not-visited); }
.tp-status.is-sent  { border-left-color: var(--accent); background: var(--tint-peach); }
.tp-status.is-live  { border-left-color: var(--q-answered); background: var(--tint-mint); }
/* Sent back by the owner. Red, because it needs the teacher to do something —
   a returned paper reading like an ordinary draft is how it gets forgotten. */
.tp-status.is-sentback { border-left-color: var(--q-not-answered); background: #fef2f3; }

@media (max-width: 640px) {
  .ad-price-form input[type="text"] { width: 100%; }
  .ad-price-form label { flex: 1 1 100%; }
  .ad-code-row > * { flex: 1 1 100% !important; width: 100% !important; }
}

/* =========================================================================
   TEACHER PANEL HOME — hero, tiles, series table

   GREEN IS THE STAFF COLOUR, and it is scoped to `.tp-panel` on purpose.
   style.css is one hand-written stylesheet shared by 52 marketing pages whose
   primary is blue; a bare `--primary` override would repaint the whole site.
   Everything below either lives under .tp-panel or carries a .tp- prefix.
   ========================================================================= */
.tp-panel {
  --tp-green: #1f5133;
  --tp-green-deep: #14361f;
  --tp-green-soft: #eef5f0;
  --tp-green-line: #d6e5db;
}

.tp-panel .tp-newpaper {
  background: var(--tp-green);
  border-color: var(--tp-green);
}
.tp-panel .tp-newpaper:hover { background: var(--tp-green-deep); border-color: var(--tp-green-deep); }

/* Poppins, like everything else a teacher works in. (16 Aug 2026: the editorial
   serif this once contrasted against — `.ed-title` and every other Instrument
   Serif heading — moved to Poppins too, so this is no longer a special case.) */
.tp-panel-title {
  font-family: "Poppins", system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: clamp(1.45rem, 3vw, 1.9rem);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.15;
  color: var(--dark);
  margin: 0;
}

/* ---------- hero ----------
   No card, no tint, no border. The owner's call: the artwork and the sentence
   sit directly on the page. `overflow: hidden` stays — it is what stops a tall
   illustration escaping the band, not decoration. */
.tp-hero {
  position: relative;
  overflow: hidden;
  padding: 22px 0 18px;
  margin: 10px 0 4px;
  min-height: 190px;
  display: flex;
  align-items: center;
}
.tp-hero-copy { max-width: 46ch; position: relative; z-index: 1; }
.tp-hero-title {
  font-size: clamp(1.25rem, 2.4vw, 1.6rem);
  line-height: 1.25;
  color: var(--tp-green-deep);
  margin: 0 0 8px;
  letter-spacing: -0.01em;
}
.tp-hero-copy p { margin: 0; color: #4a6353; font-size: 0.92rem; max-width: 38ch; }

/* Absolutely placed, so however tall the illustration is it can never decide
   the height of this band — the mistake the Ultimate PYQs hero made with its
   transparent canvas, and the reason those PNGs were trimmed on conversion. */
.tp-hero-art {
  position: absolute;
  inset: 0 0 0 auto;
  width: min(52%, 460px);
  pointer-events: none;
}
/* Sized by HEIGHT, not width. Width-sized art overflowed the band and the
   card's overflow:hidden cropped the top off the lamp without complaining —
   a 900x531 source at 92% of the column came out 250px tall inside a 170px
   card. Height-relative sizing cannot do that at any viewport. */
.tp-hero-art img { position: absolute; width: auto; max-width: none; }
.tp-art-cloud { height: 78%; right: 1%; top: 9%;    opacity: 0.7; }
.tp-art-desk  { height: 86%; right: 4%; bottom: 7%; }

/* ---------- the four numbers ---------- */
.tp-tiles {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 14px;
  margin-bottom: 26px;
}
.tp-tile {
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 16px 18px;
}
.tp-tile strong {
  display: block;
  font-size: 1.7rem;
  font-weight: 700;
  line-height: 1.1;
  color: var(--tp-green);
  font-variant-numeric: tabular-nums;
}
.tp-tile span { display: block; margin-top: 3px; font-size: 0.79rem; color: var(--muted); }

/* ---------- series table ---------- */
.tp-sectionhead { display: flex; align-items: baseline; justify-content: space-between; margin: 4px 0 12px; }
.tp-sectionhead h3 { font-size: 1rem; margin: 0; }

/* A table is the one element that must be allowed to scroll sideways rather
   than force the page to. */
.tp-tablewrap { overflow-x: auto; border: 1px solid var(--border); border-radius: 14px; background: #fff; }
.tp-table { width: 100%; border-collapse: collapse; font-size: 0.86rem; min-width: 620px; }
.tp-table th {
  text-align: left;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--muted);
  font-weight: 700;
  padding: 12px 16px;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
.tp-table td { padding: 13px 16px; border-bottom: 1px solid #f0f2f7; vertical-align: middle; }
.tp-table tr:last-child td { border-bottom: 0; }
.tp-table strong { display: block; font-weight: 600; }
.tp-table .ad-meta { display: block; font-size: 0.74rem; }
.tp-table .tp-num { font-variant-numeric: tabular-nums; white-space: nowrap; }
.tp-table tr.ts-others { background: var(--bg-soft); }
.tp-table .ts-lock { font-size: 0.74rem; color: var(--muted); }
.tp-table button { padding: 6px 14px; font-size: 0.79rem; }

/* ---------- state pills: draft / sent for review / live ---------- */
.tp-pill {
  display: inline-block;
  font-size: 0.66rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 3px 9px;
  border-radius: 999px;
  white-space: nowrap;
  background: #eef0f5;
  color: var(--muted);
}
.tp-pill + .tp-pill { margin-left: 5px; }
.tp-pill.is-live, .tp-pill.is-published { background: #e5f7ee; color: var(--q-answered); }
.tp-pill.is-sent   { background: var(--tint-peach); color: var(--accent-deep); }
.tp-pill.is-hidden, .tp-pill.is-draft { background: #eef0f5; color: var(--muted); }
.tp-pill.is-sale   { background: var(--tp-green-soft); color: var(--tp-green); }

@media (max-width: 900px) {
  .tp-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* The illustration keeps a reserved strip rather than disappearing — it is
     the only warmth on the page — but the copy gets the room it needs. */
  .tp-hero { padding: 18px 0 14px; min-height: 200px; align-items: flex-start; }
  .tp-hero-copy { max-width: 100%; }
  .tp-hero-art { width: 62%; inset: auto 0 0 auto; height: 58%; }
  .tp-art-cloud { top: auto; bottom: 30%; }
}
@media (max-width: 560px) {
  .tp-hero { min-height: 0; padding-bottom: 130px; }
  .tp-hero-art { width: 78%; height: 125px; }
  /* Create is the only one now, so it must survive the small breakpoint. */
  .tp-panel-actions { flex-wrap: wrap; }
}

/* An empty state, with the artwork rather than a bare grey sentence. The image
   is capped by HEIGHT for the same reason the hero is: tp-plant is a portrait
   400x555 and a width cap would make it tower over the text. */
.tp-empty {
  text-align: center;
  padding: 30px 20px 34px;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 14px;
}
.tp-empty img { height: 96px; width: auto; max-width: 100%; opacity: 0.9; margin-bottom: 10px; }
.tp-empty strong { display: block; font-size: 0.98rem; color: var(--text); }
.tp-empty span { display: block; margin-top: 3px; font-size: 0.85rem; color: var(--muted); }

/* =========================================================================
   TEACHER PANEL — one header bar
   Greeting left, tabs centre, actions right. The tabs used to sit on their
   own row under the title, which spent a whole band of vertical space before
   any actual work appeared on screen.
   ========================================================================= */
.tp-panel .tp-panel-head {
  align-items: center;
  gap: 16px 24px;
  margin-bottom: 20px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--border);
}
.tp-panel .tp-panel-title { flex: 0 0 auto; }

/* The tabs lose their own underline — the header bar already carries one, and
   two rules 14px apart read as a mistake. */
.tp-panel .tp-modes {
  flex: 1 1 auto;
  border-bottom: 0;
  margin-bottom: 0;
  justify-content: center;
}
.tp-panel .tp-modes .ad-tab { padding-bottom: 6px; }
.tp-panel .tp-panel-actions { flex: 0 0 auto; }
.tp-panel .ad-who { font-size: .8rem; color: var(--muted); }

/* Which paper you are editing, beside the way back out. */
.tp-editbar { display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap; margin-bottom: 6px; }
.tp-editbar .tp-back { padding-bottom: 0; }
.tp-edit-title {
  font-size: 1.15rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--dark);
  margin: 0 0 16px;
}

@media (max-width: 1080px) {
  /* Centring stops being possible once the row wraps, so the tabs take a full
     line of their own and sit left, where a tab strip belongs. */
  .tp-panel .tp-modes { order: 3; flex-basis: 100%; justify-content: flex-start; }
  .tp-panel .tp-panel-title { flex: 1 1 auto; }
}
@media (max-width: 560px) {
  .tp-panel .ad-who { display: none; }   /* the address is on the account page */
  .tp-panel .tp-panel-title { font-size: 1.3rem; }
}

/* The owner's inbox: papers a teacher has finished that are not in a series
   yet. Marked rather than merely sorted first — a row that looks like every
   other row does not read as "this one needs you".

   The amber .ad-orphan-note BANNER that used to sit above this list is gone,
   and its rule with it rather than left behind as dead CSS (§8 already carries
   a list of orphaned classes and does not need more). How many papers go into
   a series is the owner's decision, so a paper sitting outside one is a normal
   permanent state — a warning that can never be cleared by doing the right
   thing is one nobody reads. The quiet left-edge mark below stays. */
.ad-staff-row.is-orphan { border-left: 3px solid var(--accent); }
.ad-series-pick { max-width: 240px; font-size: .82rem; }
.ad-series-pick:disabled { opacity: .55; cursor: not-allowed; }

/* =========================================================================
   THE TEACHER'S TIMETABLE — drag-and-drop week
   Driven by js/timetable.js. Prefix .tt-*.
   ========================================================================= */
.tt-wrap { --tt-line: #e8ebf2; }

.tt-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin-bottom: 10px; }
.tt-head h3 { font-size: 1.15rem; margin: 0 0 2px; letter-spacing: -0.01em; }
.tt-head p { margin: 0; font-size: 0.82rem; color: var(--muted); }
.tt-actions { display: flex; align-items: center; gap: 10px; }
.tt-actions .btn { padding: 8px 16px; font-size: 0.82rem; }

/* The dirty indicator says a NUMBER when there is unsaved work: "unsaved"
   alone does not tell you whether you are about to lose one drag or twenty. */
.tt-savedpill { font-size: 0.76rem; font-weight: 700; padding: 6px 12px; border-radius: 999px; white-space: nowrap; }
.tt-savedpill.is-clean { background: var(--tint-mint); color: var(--q-answered); }
.tt-savedpill.is-dirty { background: var(--tint-peach); color: var(--accent-deep); }

.tt-msg { margin: 0 0 10px; font-size: 0.84rem; }
.tt-msg.ok { color: var(--q-answered); }
.tt-msg.bad { color: var(--q-not-answered); }

.tt-bar { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 12px; }
.tt-nav { display: flex; align-items: center; gap: 4px; border: 1px solid var(--border); border-radius: 10px; padding: 4px 6px; background: #fff; }
.tt-nav button { background: none; border: 0; font-size: 1.15rem; line-height: 1; color: var(--muted); padding: 4px 10px; border-radius: 7px; }
.tt-nav button:hover { background: var(--bg-soft); color: var(--text); }
.tt-nav span { font-size: 0.85rem; font-weight: 600; min-width: 168px; text-align: center; }
.tt-barright { display: flex; align-items: center; gap: 10px; }
.tt-barright .btn { padding: 8px 16px; font-size: 0.82rem; }
.tt-views { display: flex; border: 1px solid var(--border); border-radius: 10px; overflow: hidden; background: #fff; }
.tt-views button { background: none; border: 0; padding: 8px 15px; font-size: 0.82rem; font-weight: 600; color: var(--muted); }
.tt-views button.active { background: var(--tp-green, #1f5133); color: #fff; }

.tt-layout { display: grid; grid-template-columns: minmax(0, 1fr) 236px; gap: 16px; align-items: start; }

/* ---------- the calendar ---------- */
.tt-cal { border: 1px solid var(--border); border-radius: 14px; background: #fff; overflow: hidden; }
.tt-headrow,
.tt-grid { display: grid; grid-template-columns: 62px repeat(var(--tt-cols, 7), minmax(0, 1fr)); }
.tt-headrow { border-bottom: 1px solid var(--tt-line); background: var(--bg-soft); }
.tt-timecol { font-size: 0.7rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted); padding: 10px 8px; }
.tt-dayhead { padding: 8px 6px; text-align: center; border-left: 1px solid var(--tt-line); }
.tt-dayhead strong { display: block; font-size: 0.8rem; }
.tt-dayhead span { display: block; font-size: 0.7rem; color: var(--muted); }
.tt-dayhead.is-today strong { color: var(--tp-green, #1f5133); }
.tt-dayhead.is-today span { color: var(--tp-green, #1f5133); font-weight: 600; }

.tt-grid { position: relative; }
.tt-grid.is-loading { opacity: 0.5; pointer-events: none; }
.tt-times { border-right: 1px solid var(--tt-line); }
.tt-hour { position: relative; }
.tt-hour span { position: absolute; top: -7px; right: 7px; font-size: 0.68rem; color: var(--muted); white-space: nowrap; }
.tt-col { position: relative; border-left: 1px solid var(--tt-line); min-height: 100%; }
.tt-lines i { display: block; border-bottom: 1px solid #f2f4f9; }

/* ---------- a period ---------- */
.tt-block {
  position: absolute;
  left: 3px; right: 3px;
  border-radius: 8px;
  border-left: 3px solid currentColor;
  padding: 4px 7px;
  overflow: hidden;
  cursor: grab;
  font-size: 0.7rem;
  line-height: 1.25;
  touch-action: none;          /* the page must not scroll under a touch-drag */
  user-select: none;
}
.tt-block strong { display: block; font-size: 0.74rem; font-weight: 700; }
.tt-when { display: block; font-size: 0.63rem; opacity: 0.8; }
.tt-where { display: block; font-size: 0.63rem; opacity: 0.75; }
.tt-block.is-dragging { cursor: grabbing; opacity: 0.85; box-shadow: var(--shadow-lg); z-index: 5; }

/* Unsaved work must look different from saved work, or Reset appears to do
   nothing at all. */
.tt-block.is-unsaved { outline: 2px dashed currentColor; outline-offset: -2px; }
.tt-block.is-cancelled { opacity: 0.45; text-decoration: line-through; }

/* Another teacher on a batch you share. Not editable, and it must not look
   editable. */
.tt-block.is-ghost { background: repeating-linear-gradient(45deg, #f4f6fa, #f4f6fa 5px, #eceff6 5px, #eceff6 10px); color: #9aa3b2; border-left-color: #cfd6e4; cursor: default; }
.tt-block.is-ghost strong { font-weight: 600; }

.tt-resize { position: absolute; left: 0; right: 0; bottom: 0; height: 8px; cursor: ns-resize; }
.tt-resize::after { content: ""; position: absolute; left: 50%; bottom: 2px; width: 22px; height: 2px; margin-left: -11px; border-radius: 2px; background: currentColor; opacity: 0.35; }

.tt-del { position: absolute; right: 4px; top: 4px; background: #fff; border: 1px solid var(--border); border-radius: 6px; font-size: 0.63rem; font-weight: 700; padding: 2px 7px; color: var(--q-not-answered); }

.tt-floating { position: fixed; width: 150px; z-index: 60; pointer-events: none; box-shadow: var(--shadow-lg); opacity: 0.9; }
.tt-floating.is-over { opacity: 1; }

/* ---------- tones, straight off the design tokens ---------- */
.tone-jee   { background: var(--tint-mint);  color: #14804a; }
.tone-neet  { background: var(--tint-blue);  color: var(--primary); }
.tone-found { background: var(--tint-peach); color: var(--accent-deep); }
.tone-other { background: var(--tint-lav);   color: #6d3fd4; }

/* ---------- the palette ---------- */
.tt-side { border: 1px solid var(--border); border-radius: 14px; background: #fff; padding: 14px; }
.tt-side h4 { font-size: 0.9rem; margin: 0; }
.tt-sidenote { font-size: 0.74rem; color: var(--muted); margin: 2px 0 12px; }
.tt-chip {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  border-radius: 10px; padding: 10px 11px; margin-bottom: 8px;
  cursor: grab; touch-action: none; user-select: none;
  border-left: 3px solid currentColor;
}
.tt-chip strong { display: block; font-size: 0.79rem; font-weight: 700; }
.tt-chip span { font-size: 0.7rem; opacity: 0.8; }
.tt-chip:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.tt-grip { opacity: 0.45; font-size: 0.8rem; letter-spacing: -2px; }
.tt-emptypal { font-size: 0.78rem; color: var(--muted); line-height: 1.5; }

.tt-tip { margin-top: 14px; padding: 11px 12px; border-radius: 10px; background: var(--bg-soft); font-size: 0.72rem; color: var(--muted); line-height: 1.5; }
.tt-tip strong { display: block; color: var(--text); font-size: 0.76rem; margin-bottom: 2px; }

.tt-legend { display: flex; gap: 16px; flex-wrap: wrap; margin-top: 12px; font-size: 0.72rem; color: var(--muted); }
.tt-legend span { display: inline-flex; align-items: center; gap: 6px; }
.tt-legend span::before { content: ""; width: 9px; height: 9px; border-radius: 50%; background: currentColor; }

/* ---------- just this week, or every week? ---------- */
.tt-ask { position: fixed; inset: 0; background: rgba(20, 25, 43, 0.35); display: flex; align-items: center; justify-content: center; z-index: 80; padding: 20px; }
.tt-askbox { background: #fff; border-radius: 14px; padding: 22px; width: min(340px, 100%); box-shadow: var(--shadow-lg); text-align: center; }
.tt-askbox strong { display: block; font-size: 0.95rem; margin-bottom: 14px; }
.tt-askbox .btn { width: 100%; margin-bottom: 8px; }
.tt-askcancel { background: none; border: 0; color: var(--muted); font-size: 0.8rem; padding: 4px; }

@media (max-width: 1000px) {
  /* The palette goes above the grid rather than beside it. A 236px rail on a
     tablet leaves the week too narrow to read, and the week is the point. */
  .tt-layout { grid-template-columns: minmax(0, 1fr); }
  .tt-side { order: -1; }
  .tt-side > div:not(.tt-tip) { display: flex; gap: 8px; overflow-x: auto; padding-bottom: 4px; }
  .tt-chip { flex: 0 0 auto; min-width: 150px; margin-bottom: 0; }
}
@media (max-width: 700px) {
  /* Seven columns cannot be read on a phone. The grid scrolls sideways inside
     its own card — the page itself never does. */
  .tt-cal { overflow-x: auto; }
  .tt-headrow, .tt-grid { min-width: 620px; }
  .tt-head, .tt-bar { gap: 10px; }
  .tt-actions { width: 100%; }
  .tt-actions .btn { flex: 1 1 auto; }
}

/* --- timetable refinements ---------------------------------------------- */

/* The remove control is a CROSS, not the word "Remove". A period can be 30
   minutes tall, and on a phone the column is ~80px wide — a labelled button
   simply spilled out of the block it belonged to. */
.tt-del {
  right: 3px; top: 3px;
  width: 18px; height: 18px;
  padding: 0;
  display: grid; place-items: center;
  font-size: 0.8rem; line-height: 1;
  border-radius: 50%;
}
.tt-del:hover { background: var(--q-not-answered); color: #fff; border-color: var(--q-not-answered); }

/* How long this teacher's class runs. 60, 90 and 120 are all normal and it
   differs per teacher and per batch, so it is typed rather than assumed. */
.tt-chip { position: relative; }
.tt-chipmain { min-width: 0; }
.tt-chipmenu {
  background: none; border: 0;
  font-size: 1rem; line-height: 1;
  color: currentColor; opacity: 0.5;
  padding: 4px 2px; border-radius: 6px;
  cursor: pointer; flex: 0 0 auto;
}
.tt-chipmenu:hover { opacity: 1; background: rgba(255, 255, 255, 0.6); }
.tt-lenbox {
  position: absolute; right: 6px; top: calc(100% - 6px); z-index: 20;
  display: flex; align-items: flex-end; gap: 6px;
  background: #fff; border: 1px solid var(--border); border-radius: 10px;
  padding: 9px 10px; box-shadow: var(--shadow);
}
.tt-lenbox label { display: flex; flex-direction: column; gap: 3px; font-size: 0.68rem; font-weight: 600; color: var(--muted); }
.tt-leninput { width: 68px; border: 1px solid var(--border); border-radius: 7px; padding: 5px 7px; font: inherit; font-size: 0.8rem; }
.tt-lenok { border: 0; border-radius: 7px; padding: 6px 11px; font-size: 0.76rem; font-weight: 700; background: var(--tp-green, #1f5133); color: #fff; cursor: pointer; }

/* The head has no subtitle now, so it should not reserve space for one. */
.tt-head h3 { margin-bottom: 0; }

/* =========================================================================
   TEACHER PANEL — four-destination header
   Home · Schedule · Library · Papers, one Create action, and an avatar that
   carries identity on a phone where the email used to be display:none.
   ========================================================================= */

/* Four items, a longer button label and an avatar on one row. The old rule
   only dropped the tabs to their own line at 1080px and this wraps above that. */
@media (max-width: 1180px) {
  .tp-panel .tp-modes { order: 3; flex-basis: 100%; justify-content: flex-start; }
  .tp-panel .tp-panel-title { flex: 1 1 auto; }
}

.tp-me { position: relative; flex: 0 0 auto; }
.tp-avatar {
  display: grid;
  place-items: center;
  width: 36px; height: 36px;
  border-radius: 50%;
  background: var(--tp-green, #1f5133);
  color: #fff;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  cursor: pointer;
  overflow: hidden;
  user-select: none;
}
.tp-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }

.tp-menu {
  position: absolute;
  right: 0; top: calc(100% + 8px);
  z-index: 40;
  min-width: 210px;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: var(--shadow-lg);
  padding: 12px;
  display: grid;
  gap: 10px;
}
/* The address is no longer hidden on small screens — it is behind the avatar
   now, which is a tap rather than a squeeze. */
.tp-menu .ad-who { display: block !important; font-size: 0.78rem; color: var(--muted); word-break: break-all; }
.tp-menu .btn-signout { width: 100%; margin: 0; }

@media (max-width: 560px) {
  .tp-panel .tp-panel-title { font-size: 1.3rem; }
  .tp-panel .tp-newpaper { padding: 8px 14px; font-size: 0.8rem; }
}

/* =========================================================================
   PAPERS, THE SCREENSHOT DROP ZONE, AND SOURCE YEARS
   ========================================================================= */

/* Paste a screenshot straight in. A teacher photographing a past paper has the
   image on the clipboard, never on disk. */
.tp-paste {
  border: 2px dashed var(--border);
  border-radius: 12px;
  padding: 18px 16px;
  text-align: center;
  background: var(--bg-soft);
  cursor: pointer;
  transition: border-color .12s, background .12s;
}
.tp-paste:hover, .tp-paste:focus-visible { border-color: var(--tp-green, #1f5133); }
.tp-paste.is-over { border-color: var(--tp-green, #1f5133); background: var(--tint-mint); }
.tp-paste strong { display: block; font-size: .86rem; }
.tp-paste span { display: block; margin-top: 2px; font-size: .74rem; color: var(--muted); }
.tp-paste label { color: var(--primary); text-decoration: underline; cursor: pointer; }
/* The file input stays reachable — the label above points at it — but it is no
   longer the primary affordance. */
.tp-upload input[type="file"] { font-size: .78rem; margin-top: 8px; }

/* Which past paper a question came from. Shown to the student in the player
   and again on the result page. */
.tp-qsrc {
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .03em;
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--tint-blue);
  color: var(--primary);
  white-space: nowrap;
}
.rs-q-src { font-size: .7rem; color: var(--muted); margin-bottom: 4px; font-weight: 600; }
.lb-year { font-size: .7rem; padding: 2px 7px; border-radius: 999px; background: var(--bg-soft); color: var(--muted); font-weight: 600; }

/* Library toolbar: the year filter sits beside the reviewed/selected chips. */
.lb-toolbar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
select.lb-year {
  font-size: .8rem; padding: 6px 10px; border-radius: 9px;
  border: 1px solid var(--border); background: #fff; color: var(--text);
  max-width: 190px; font-weight: 500;
}

/* Offline tests, re-homed onto Papers. Set apart from the online papers above
   it, because they are a different kind of thing that happens to share a list. */
.tp-offline {
  margin-top: 22px;
  padding-top: 20px;
  border-top: 1px solid var(--border);
}

@media (max-width: 640px) {
  .lb-toolbar { width: 100%; }
  select.lb-year { max-width: 100%; flex: 1 1 100%; }
}

/* Practice / Ranked, in the console. It drops onto its own line under the paper
   it belongs to, so it can never be mistaken for the controls of the row below. */
.ad-staff-row .ad-modeform { flex: 1 1 100%; }
.ad-modeform {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 12px;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px dashed var(--border);
}
.ad-modeform label { display: flex; flex-direction: column; gap: 4px; font-size: 0.78rem; font-weight: 600; color: var(--muted); }
.ad-modeform input[type="datetime-local"],
.ad-modeform select {
  border: 1px solid var(--border);
  border-radius: 9px;
  padding: 7px 9px;
  font: inherit;
  font-size: 0.82rem;
}
.ad-rankedbits { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px; flex: 1 1 100%; }
.ad-modeform .md-msg { flex: 1 1 100%; margin: 0; }

@media (max-width: 640px) {
  .ad-modeform label,
  .ad-rankedbits label { flex: 1 1 100%; }
  .ad-modeform input[type="datetime-local"],
  .ad-modeform select { width: 100%; }
}

/* =========================================================================
   TEACHER HOME — the batch dashboard
   Scoped under .tp-panel like the rest of the teaching panel.
   ========================================================================= */
.an-wrap { margin-top: 26px; }

.an-bar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 14px; }
.an-bar .ad-select { max-width: 260px; }
.an-ranges { display: flex; border: 1px solid var(--border); border-radius: 10px; overflow: hidden; background: #fff; }
.an-ranges button { background: none; border: 0; padding: 8px 14px; font-size: 0.8rem; font-weight: 600; color: var(--muted); }
.an-ranges button.active { background: var(--tp-green, #1f5133); color: #fff; }

.an-cards { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; margin-bottom: 18px; }
.an-card { background: #fff; border: 1px solid var(--border); border-radius: 14px; padding: 15px 17px; }
.an-card strong {
  display: block;
  font-size: 1.55rem; font-weight: 700; line-height: 1.1;
  color: var(--tp-green, #1f5133);
  font-variant-numeric: tabular-nums;
}
.an-card span { display: block; margin-top: 3px; font-size: 0.78rem; color: var(--muted); }
.an-card em { display: block; margin-top: 6px; font-size: 0.72rem; font-style: normal; color: var(--muted); }
.an-card.is-up em { color: var(--q-answered); font-weight: 600; }
.an-card.is-down em { color: var(--q-not-answered); font-weight: 600; }

.an-grid { display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); gap: 16px; align-items: start; }
.an-panel { background: #fff; border: 1px solid var(--border); border-radius: 14px; padding: 16px 18px; }
.an-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 12px; }
.an-head h3 { font-size: 0.95rem; margin: 0; }
/* The honest-limits line: which tests are NOT on the chart, and why. */
.an-head span { font-size: 0.72rem; color: var(--muted); flex: 1 1 100%; line-height: 1.5; }

.an-chartwrap { position: relative; }
.an-svg { width: 100%; height: auto; display: block; overflow: visible; }
.an-grid-line { stroke: #eef0f5; stroke-width: 1; }
.an-axis { font-size: 9px; fill: var(--muted); }
.an-line { fill: none; stroke: var(--tp-green, #1f5133); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.an-dot { fill: #fff; stroke: var(--tp-green, #1f5133); stroke-width: 2; cursor: pointer; }
.an-dot:hover, .an-dot:focus { fill: var(--tp-green, #1f5133); outline: none; }

.an-tip {
  position: absolute; top: 4px; left: 40px;
  background: var(--dark); color: #fff;
  font-size: 0.72rem; padding: 6px 10px; border-radius: 8px;
  pointer-events: none; max-width: 90%;
}
.an-legend { display: flex; flex-wrap: wrap; gap: 6px 14px; margin-top: 10px; font-size: 0.71rem; color: var(--muted); }

.an-row {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 10px 0; border-bottom: 1px solid #f0f2f7;
}
.an-row:last-child { border-bottom: 0; }
.an-row strong { display: block; font-size: 0.85rem; font-weight: 600; }
.an-row .ad-meta { display: block; font-size: 0.73rem; }
.an-drop {
  font-size: 0.75rem; font-weight: 700; white-space: nowrap;
  color: var(--q-not-answered); background: #fdeaec;
  padding: 3px 9px; border-radius: 999px;
}

@media (max-width: 1000px) {
  .an-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .an-grid { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 560px) {
  .an-bar .ad-select { max-width: 100%; flex: 1 1 100%; }
  .an-ranges { flex: 1 1 100%; }
  .an-ranges button { flex: 1 1 auto; }
}

/* =========================================================================
   PAPER EDITOR — two panes
   Left: what is in the paper. Right: where the next question comes from.
   ========================================================================= */
/* The right pane used to be minmax(0, 420px) — a hard cap, not a fraction, so
   it never grew however wide the screen was. Inside it the library kept its own
   260px chapter rail, which left ~116px for the question text and rendered
   stems one word per line. It is a user-dragged split now, clamped so neither
   side can be starved. --tp-split is written by the gutter drag and remembered
   in localStorage. */
.tp-twopane {
  display: grid;
  grid-template-columns: var(--tp-split, 1fr) 9px minmax(0, 1fr);
  gap: 0;
  align-items: stretch;
}
.tp-pane-left { min-width: 0; padding-right: 18px; }
.tp-pane-right {
  min-width: 0;
  padding-left: 18px;
  position: sticky;
  top: 16px;
  /* The library pane scrolls on its own. Without this the question list on the
     left has to be scrolled past before the library is reachable at all. */
  max-height: calc(100dvh - 40px);
  overflow-y: auto;
}

/* the divider you drag */
.tp-gutter {
  position: relative;
  cursor: col-resize;
  background: var(--border);
  border-radius: 2px;
  transition: background 0.15s;
}
.tp-gutter::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 3px;
  height: 36px;
  border-radius: 2px;
  background: #c3cbd8;
}
.tp-gutter:hover,
.tp-gutter.is-drag { background: var(--tp-green-line, #cfe3d7); }
.tp-gutter:hover::after,
.tp-gutter.is-drag::after { background: var(--tp-green, #1f5133); }
body.tp-resizing { cursor: col-resize; user-select: none; }

.tp-panetabs { display: flex; gap: 4px; border-bottom: 2px solid var(--border); margin-bottom: 14px; }
.tp-panetabs button {
  background: none; border: 0;
  padding: 8px 12px;
  font-size: 0.82rem; font-weight: 600;
  color: var(--muted);
  border-bottom: 2px solid transparent;
  margin-bottom: -2px;
}
.tp-panetabs button.active { color: var(--tp-green, #1f5133); border-bottom-color: var(--tp-green, #1f5133); }

.tp-panebody { margin-top: 12px; }
/* The picker is MOVED into this pane, not re-created, so it keeps its own
   layout. It only needs to stop assuming full page width. */
.tp-panebody #lbRoot { display: block; }
/* ⚠ THIS LINE USED TO SAY .lb-layout, AND .lb-layout EXISTS NOWHERE.
   It appeared exactly once in the whole of public/ — here — so it matched
   nothing, and the picker kept .lb-wrap's `260px minmax(0,1fr)` grid inside a
   420px pane: 400 − 260 − 24 = 116px for every question, which is why stems
   rendered one word per line with the maths broken across it.
   The container the picker actually uses is .lb-wrap. */
.tp-panebody .lb-wrap { grid-template-columns: minmax(0, 1fr); gap: 12px; }
/* Stacked above the list now rather than beside it, and bounded so it cannot
   push the questions off the bottom of the pane. */
.tp-panebody .lb-nav {
  position: static;
  max-height: 190px;
  overflow-y: auto;
  top: auto;
}
.tp-panebody .lb-head { flex-wrap: wrap; gap: 8px; }
.tp-panebody .lb-toolbar { flex-wrap: wrap; }

/* ---- the two-step wizard ---- */
.tp-wz { display: flex; align-items: center; gap: 10px; margin-left: auto; }
.tp-wz-step {
  display: flex;
  align-items: center;
  gap: 8px;
  background: none;
  border: 0;
  padding: 4px 2px;
  font-size: 0.8rem;
  color: var(--muted);
  cursor: pointer;
  white-space: nowrap;
}
.tp-wz-num {
  width: 23px;
  height: 23px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-size: 0.72rem;
  font-weight: 700;
  background: var(--border);
  color: var(--muted);
  flex: none;
}
.tp-wz-step.is-on { color: var(--text); font-weight: 650; }
.tp-wz-step.is-on .tp-wz-num { background: var(--tp-green, #1f5133); color: #fff; }
.tp-wz-step.is-done { color: var(--text); }
.tp-wz-step.is-done .tp-wz-num {
  background: var(--tp-green-soft, #eaf3ee);
  color: var(--tp-green, #1f5133);
}
.tp-wz-step[disabled] { opacity: 0.45; cursor: not-allowed; }
.tp-wz-line { width: 34px; height: 2px; border-radius: 2px; background: var(--border); flex: none; }
.tp-wz-line.is-done { background: var(--tp-green-line, #cfe3d7); }

/* ---- the running tally under step 1 ---- */
.tp-tally {
  display: flex;
  border: 1px solid var(--tp-green-line, #cfe3d7);
  border-radius: 12px;
  overflow: hidden;
  background: var(--tp-green-soft, #eaf3ee);
  margin-top: 14px;
}
.tp-tally div {
  flex: 1;
  padding: 12px 16px;
  border-right: 1px solid var(--tp-green-line, #cfe3d7);
}
.tp-tally div:last-child { border-right: 0; }
.tp-tally b {
  display: block;
  font-size: 1.15rem;
  font-weight: 700;
  letter-spacing: -0.4px;
  color: var(--tp-green, #1f5133);
}
.tp-tally small { font-size: 0.7rem; color: var(--muted); }

@media (max-width: 1100px) {
  /* Stacked, so there is nothing to drag. The custom property is overridden
     rather than inherited, or a width saved on a desktop would survive here as
     a first column the layout no longer has. */
  .tp-twopane { grid-template-columns: minmax(0, 1fr) !important; }
  .tp-gutter { display: none; }
  .tp-pane-left { padding-right: 0; }
  .tp-pane-right {
    border-left: 0;
    padding-left: 0;
    border-top: 1px solid var(--border);
    padding-top: 18px;
    position: static;
    max-height: none;
  }
  .tp-wz { margin-left: 0; width: 100%; }
}


/* =========================================================
   OWNER CONSOLE - "The Workspace" shell
   admin.html only. Everything here is scoped under .ac-body or
   .ac-shell, for the same reason the green teacher panel is scoped
   under .tp-panel: this stylesheet is shared by ~52 marketing pages
   and an unscoped rule repaints all of them.

   Layout choice worth keeping: the sidebar is position:sticky inside
   a normally-scrolling page, NOT a fixed rail over an overflow:auto
   content pane. It looks identical and it cannot trap scrollIntoView,
   break a modal, or fight the global overflow-x:clip on body.
   ========================================================= */

/* The opt-out from the sticky-footer flex rule is expressed at that rule
   itself (body:not(.tp-body):not(.ac-body)), not as an override here, so it
   cannot be undone by source order.

   --header-h is redeclared because this page HAS no .site-header any more.
   The token is 64px globally and .lb-nav — live on the Library panel — sizes
   its sticky chapter rail from it. Left at 64 it would be measuring against a
   header that does not exist. Declared on the scoping root, so it is inherited
   here and repaints nothing else. */
body.ac-body {
  --header-h: 58px;
  background: var(--bg-soft);
}

.ac-shell { display: flex; align-items: flex-start; min-height: 100dvh; }

/* ---------- the rail ---------- */
.ac-side {
  width: 228px;
  flex: none;
  align-self: stretch;
  position: sticky;
  top: 0;
  height: 100dvh;
  overflow-y: auto;
  background: var(--dark);
  color: #fff;
  padding: 16px 0 10px;
  display: flex;
  flex-direction: column;
  scrollbar-width: thin;
}
.ac-brand {
  padding: 2px 18px 16px;
  font-size: 1.02rem;
  font-weight: 800;
  letter-spacing: -0.3px;
  color: #fff;
}
.ac-brand span { color: #7aa7f5; }
.ac-brand small {
  display: block;
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.38);
  margin-top: 1px;
}
.ac-group {
  padding: 15px 18px 5px;
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 1.1px;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.34);
}
.ac-link {
  display: flex;
  align-items: center;
  gap: 11px;
  width: 100%;
  padding: 8px 18px;
  font-size: 0.85rem;
  font-weight: 400;
  text-align: left;
  color: rgba(255, 255, 255, 0.72);
  background: none;
  border: 0;
  position: relative;
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.ac-link:hover { color: #fff; background: rgba(255, 255, 255, 0.05); }
.ac-link.active {
  color: #fff;
  font-weight: 600;
  background: rgba(122, 167, 245, 0.16);
}
.ac-link.active::before {
  content: "";
  position: absolute;
  left: 0;
  top: 6px;
  bottom: 6px;
  width: 3px;
  border-radius: 0 3px 3px 0;
  background: #7aa7f5;
}
.ac-link svg {
  width: 17px;
  height: 17px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.ac-link .ac-badge { margin-left: auto; }
.ac-badge {
  display: inline-grid;
  place-items: center;
  min-width: 19px;
  height: 19px;
  padding: 0 6px;
  border-radius: 999px;
  font-size: 0.66rem;
  font-weight: 700;
  background: rgba(255, 255, 255, 0.14);
  color: rgba(255, 255, 255, 0.85);
}
.ac-badge.hot { background: var(--q-not-answered); color: #fff; }
.ac-badge.warm { background: var(--accent); color: #fff; }
.ac-badge[hidden] { display: none !important; }

/* A red dot on Home whenever the alarm band has something in it. The alarm
   itself lives on Home, so without this it would be invisible from every
   other screen - which is the exact bug moving it there could reintroduce. */
.ac-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--q-not-answered);
  margin-left: auto;
  flex: none;
  box-shadow: 0 0 0 3px rgba(224, 52, 74, 0.25);
}
.ac-dot[hidden] { display: none !important; }

.ac-side-foot {
  margin-top: auto;
  padding: 12px 18px 4px;
  border-top: 1px solid rgba(255, 255, 255, 0.09);
}
.ac-side-foot small {
  display: block;
  font-size: 0.64rem;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.38);
}
.ac-side-foot .ad-who {
  font-size: 0.74rem;
  color: rgba(255, 255, 255, 0.8);
  word-break: break-all;
}

/* ---------- main column ---------- */
.ac-main { flex: 1; min-width: 0; }

.ac-top {
  position: sticky;
  top: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  gap: 14px;
  height: 58px;
  padding: 0 26px;
  background: #fff;
  border-bottom: 1px solid var(--border);
}
/* Poppins, same as `.ed-title` and every other former Instrument Serif heading
   (16 Aug 2026) — the editorial serif this once deliberately avoided is gone
   sitewide, same call as the teacher panel above. */
.ac-title {
  font-family: inherit;
  font-size: 1.05rem;
  font-weight: 700;
  letter-spacing: -0.2px;
  margin: 0;
}
.ac-top-actions { margin-left: auto; display: flex; align-items: center; gap: 10px; }

/* Quiet by default — signing out is not the thing you came here to do — but it
   turns red on hover so it never reads as just another toolbar button. */
.ac-signout {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 36px;
  padding: 0 14px;
  border: 1px solid var(--border);
  border-radius: 9px;
  background: #fff;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--muted);
  cursor: pointer;
  transition: color 0.15s, border-color 0.15s, background 0.15s;
}
.ac-signout:hover {
  color: var(--q-not-answered);
  border-color: #f3c6cc;
  background: #fff6f7;
}
.ac-signout svg {
  width: 16px;
  height: 16px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.ac-signout[hidden] { display: none !important; }

.ac-content { padding: 20px 26px 44px; }

/* ---------- home ---------- */
.ac-kpis {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 13px;
  margin: 16px 0;
}
.ac-kpi {
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 13px;
  padding: 14px 16px;
  position: relative;
  overflow: hidden;
}
.ac-kpi::after {
  content: "";
  position: absolute;
  right: -18px;
  top: -18px;
  width: 62px;
  height: 62px;
  border-radius: 50%;
  opacity: 0.55;
}
.ac-kpi.t1::after { background: var(--tint-peach); }
.ac-kpi.t2::after { background: var(--tint-blue); }
.ac-kpi.t3::after { background: var(--tint-mint); }
.ac-kpi.t4::after { background: var(--tint-lav); }
.ac-kpi small,
.ac-kpi b,
.ac-kpi .ac-sub { position: relative; z-index: 1; }
.ac-kpi small { display: block; font-size: 0.72rem; color: var(--muted); }
.ac-kpi b {
  display: block;
  font-size: 1.65rem;
  font-weight: 700;
  letter-spacing: -1px;
  line-height: 1.25;
}
.ac-kpi b.hot { color: var(--q-not-answered); }
.ac-kpi .ac-sub { font-size: 0.72rem; font-weight: 500; color: var(--muted); }
.ac-kpi .ac-sub.bad { color: var(--q-not-answered); font-weight: 600; }
.ac-kpi .ac-sub.ok { color: var(--q-answered); }

.ac-cols {
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
  gap: 16px;
  margin-top: 16px;
}
.ac-card { background: #fff; border: 1px solid var(--border); border-radius: 13px; }
.ac-card-h {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 13px 17px;
  border-bottom: 1px solid var(--border);
}
.ac-card-h h3 { font-size: 0.86rem; font-weight: 700; margin: 0; }
.ac-card-h svg {
  width: 16px;
  height: 16px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.ac-card-h .ac-more {
  margin-left: auto;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--primary);
  background: none;
  border: 0;
  cursor: pointer;
}
.ac-card-h .ac-more:hover { text-decoration: underline; }

.ac-row {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 11px 17px;
  border-bottom: 1px solid var(--border);
  font-size: 0.82rem;
}
.ac-row:last-child { border-bottom: 0; }
.ac-row .ac-who { min-width: 0; }
.ac-row .ac-who b { display: block; font-weight: 600; font-size: 0.83rem; }
.ac-row .ac-who small {
  display: block;
  color: var(--muted);
  font-size: 0.72rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ac-row .ac-amt { margin-left: auto; font-weight: 600; white-space: nowrap; }
.ac-row .ac-age { font-size: 0.72rem; color: var(--muted); white-space: nowrap; }
.ac-row .ac-age.late { color: var(--q-not-answered); font-weight: 700; }
.ac-thumb {
  width: 36px;
  height: 36px;
  border-radius: 8px;
  object-fit: cover;
  flex: none;
  cursor: pointer;
  border: 1px solid var(--border);
}
.ac-noshot {
  width: 36px;
  height: 36px;
  border-radius: 8px;
  flex: none;
  background: var(--bg-soft);
  border: 1px dashed var(--border);
}

.ac-act {
  display: flex;
  gap: 10px;
  padding: 10px 17px;
  border-bottom: 1px solid var(--border);
  font-size: 0.78rem;
}
.ac-act:last-child { border-bottom: 0; }
.ac-act .ac-adot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--primary);
  margin-top: 6px;
  flex: none;
}
.ac-act .ac-adot.g { background: var(--q-answered); }
.ac-act .ac-adot.o { background: var(--accent); }
.ac-act time { margin-left: auto; color: var(--muted); font-size: 0.7rem; white-space: nowrap; }
.ac-empty { padding: 16px 17px; font-size: 0.8rem; color: var(--muted); }

/* A capped query cannot be summed honestly without saying so. */
.ac-caveat {
  font-size: 0.72rem;
  color: var(--accent-deep);
  font-weight: 500;
}

/* ---------- narrow: the rail becomes a strip across the top ---------- */
@media (max-width: 900px) {
  .ac-shell { flex-direction: column; align-items: stretch; }
  .ac-side {
    width: auto;
    height: auto;
    position: sticky;
    top: 0;
    z-index: 40;
    flex-direction: row;
    align-items: center;
    padding: 0;
    overflow: visible;
  }
  /* The links live inside <nav id="adTabs">, so THAT is what has to become the
     horizontal scroller. Turning only .ac-side into a flex row leaves the nav
     a block and the eleven links stack into a 379px-tall wall that pushes the
     whole console down the page. Measured, not guessed. */
  .ac-side #adTabs {
    display: flex;
    align-items: center;
    gap: 2px;
    width: 100%;
    padding: 8px 10px;
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: none;
  }
  .ac-side #adTabs::-webkit-scrollbar { display: none; }
  .ac-brand,
  .ac-group,
  .ac-side-foot { display: none; }
  .ac-link {
    width: auto;
    flex: none;
    padding: 7px 11px;
    border-radius: 8px;
    white-space: nowrap;
    font-size: 0.78rem;
  }
  .ac-link.active::before { display: none; }
  .ac-link .ac-badge { margin-left: 4px; }
  .ac-dot { margin-left: 4px; }
  /* Two sticky bars both pinned to top:0 is one bar too many — the rail is
     z-index 40 and .ac-top is 30, so the section title and the Refresh button
     would slide underneath the rail and become unreachable. The rail is the
     one that has to stay pinned on a phone. */
  .ac-top { position: static; padding: 0 16px; height: 52px; }
  /* Keep both actions reachable on a phone without wrapping the bar: the
     labels go, the icons stay. Refresh has no icon, so it keeps its word. */
  .ac-signout span { display: none; }
  .ac-signout { padding: 0 10px; }
  .ac-content { padding: 16px 16px 34px; }
  .ac-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .ac-cols { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 560px) {
  .ac-kpi b { font-size: 1.4rem; }
  .ac-top .ac-title { font-size: 0.95rem; }
}

/* =========================================================
   Test Series — landing (.tsl-*), catalogue (.tsc-*), detail (.tsd-*)
   Built from the Claude Design wireframes, in the site's own editorial
   system: no gradients, hairline rules, blue primary on white.
   ========================================================= */

/* ---------- landing hero ---------- */
.tsl-hero { padding: 44px 0 36px; background: var(--primary-light); border-bottom: 1px solid var(--border); text-align: center; }
.tsl-hero h1 { max-width: 720px; margin: 0 auto; font-weight: 800; font-size: clamp(1.6rem, 3.4vw, 2.4rem); line-height: 1.2; letter-spacing: -.02em; color: var(--dark); }
.tsl-hero > .container > p { max-width: 560px; margin: 10px auto 0; color: var(--muted); font-size: .93rem; line-height: 1.55; }
/* .tsl-search and .tsl-hero-slim were removed here (16 Aug 2026) — the search
   bar's only markup, on this exact page, is gone in favour of the banner
   carousel. Checked before deleting: neither class was used anywhere else. */
.tsl-quick { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin-top: 14px; }
.tsl-chip { border: 1px solid var(--border); background: #fff; color: var(--text); border-radius: 999px; padding: 5px 14px; font: inherit; font-size: .78rem; cursor: pointer; transition: border-color .16s, color .16s; }
.tsl-chip:hover, .tsl-chip:focus-visible { border-color: var(--primary); color: var(--primary); outline: none; }

.tsl-body { padding-bottom: 56px; }
.tsl-sec { margin-top: 38px; }
.tsl-sec-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; padding-bottom: 10px; border-bottom: 2px solid var(--dark); }
.tsl-sec-head h2 { font-weight: 800; font-size: 1.2rem; letter-spacing: -.02em; color: var(--dark); }

/* ---------- landing cards ---------- */
.tsl-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 16px; margin-top: 18px; }
.tsl-card { display: flex; flex-direction: column; gap: 7px; padding: 16px; border: 1px solid var(--border); border-radius: 12px; background: #fff; transition: border-color .16s, box-shadow .16s; }
.tsl-card:hover { border-color: #c9d6f5; box-shadow: var(--shadow); }
.tsl-card-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.tsl-exam { font-size: .68rem; font-weight: 700; letter-spacing: .09em; text-transform: uppercase; color: var(--muted); }
/* `.tsl-badge` ("Free tests inside") was removed — the free count now lives in
   the .tsl-count one-liner instead of being said twice on one card. */
.tsl-card h3 { font-size: 1rem; line-height: 1.3; }
.tsl-card h3 a { color: var(--dark); text-decoration: none; }
.tsl-card h3 a::after { content: ""; position: absolute; inset: 0; }
.tsl-card { position: relative; }
/* The one-liner: "15 mock tests · 1 free · 300 marks". Separators are their own
   spans so they stay grey while the numbers stay dark.

   NOT display:flex. Flex makes every child its own item and DROPS the
   whitespace between them, so `<b>10</b> mock tests` rendered as "10mock
   tests". Plain inline content keeps the spaces and wraps on its own. */
.tsl-count { font-size: .82rem; color: var(--text); }
.tsl-count b { font-weight: 700; }
/* --border (#e6e9f0) is a HAIRLINE colour and is invisible as text on white —
   it left the line looking like three phrases with unexplained gaps. */
.tsl-dot { color: var(--muted); opacity: .5; margin: 0 6px; }
.tsl-free { color: var(--primary); font-weight: 600; }
.tsl-soon { color: var(--muted); font-style: italic; }

/* Free-tests shelf. The FREE tag is the green the exam engine already uses for
   a correct answer, so "free" reads as good news rather than as a warning. */
.tsl-freetag {
  flex: none; font-size: .62rem; font-weight: 800; letter-spacing: .08em;
  background: var(--q-answered); color: #fff; border-radius: 4px; padding: 3px 7px;
}
/* EXCLUSIVE sits opposite the exam kicker, in the slot the FREE tag uses on the
   free shelf — same shape, same weight, opposite meaning.

   The red is NOT --q-not-answered (#e0344a). White on that measures 4.42:1,
   and this is 10px bold uppercase, i.e. WCAG "small text", which needs 4.5.
   Just missing it is the worst kind of near-miss: it looks deliberate and it
   is not. #c81e3a is the same red family at 5.68:1. */
.tsl-exclusive {
  flex: none; font-size: .62rem; font-weight: 800; letter-spacing: .08em;
  background: #c81e3a; color: #fff; border-radius: 4px; padding: 3px 7px;
  white-space: nowrap;
}
/* A hairline, not a glow or a heavier shadow: these cards sit in a row with
   ordinary ones and the row has to stay a row. */
.tsl-card.is-exclusive { border-color: #f3c6ce; }
.tsl-sec-note { font-size: .78rem; color: var(--muted); font-weight: 500; }
.tsl-lang { font-size: .76rem; color: var(--muted); }
/* .tsl-manifest rules removed 16 Aug 2026 with the markup that produced them
   — see the note above `line1` in js/test-series-card.js. Nothing renders a
   <ul class="tsl-manifest"> any more. */
.tsl-card-foot { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: auto; padding-top: 10px; }
.tsl-price { font-size: 1.05rem; color: var(--primary); }
.tsl-price-na { font-size: .76rem; color: var(--muted); }
.tsl-card-foot .btn { position: relative; z-index: 1; padding: 7px 14px; font-size: .8rem; }

/* ---------- "Split footer" series card (owner's reference, 16 Aug 2026) ----------
   Renders under #tslCards (Popular) and inside .tsl-exam-group .tsl-cards (by
   exam, widened at its OWN rule further down — .tsl-exam-group .tsl-cards —
   rather than here, because that selector already existed later in this file
   at equal specificity and was winning the cascade over a second declaration
   here). #tslFree keeps the OLD .tsl-card shape on purpose — it was not part
   of the reference and the two card families are visually distinct now.

   OWN class namespace (tsl-sf-*), not a restyle of .tsl-card/.tsl-price/
   .tsl-mrp/.tsl-off/.tsl-per — those are shared with the series DETAIL page's
   .tsd-plan block, verified working three times this session, and this
   change had no reason to risk it. */
#tslCards {
  /* wide enough for a photo-left card to actually look like the reference,
     not a dense tile grid — fewer per row than the old .tsl-card grid, and
     that is the point: this is a spacious card, not a compact one. */
  grid-template-columns: repeat(auto-fill, minmax(460px, 1fr));
  gap: 22px;
}

/* flex column + margin-top:auto on .tsl-sf-split keeps the dark price bar
   pinned to the bottom, so cards sharing a row line their footers up even
   when one has an extra description line or a wrapped stats row. Grid already
   stretches them to equal height; without this the bar floats mid-card. */
.tsl-sf-card {
  position: relative;
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border);
  border-radius: 14px;
  overflow: hidden;
  background: #fff;
  transition: border-color .16s ease, box-shadow .16s ease;
}
.tsl-sf-card:hover { border-color: #c9d6f5; box-shadow: var(--shadow); }
.tsl-sf-card.is-exclusive { border-color: #b7c3ff; }

.tsl-sf-top { display: flex; align-items: stretch; }

/* Diagonal-cut photo, same idea as the reference. No image exists yet for any
   exam, so the fill is a soft blue tint — an intentional placeholder colour,
   not a "broken image" grey box — until EXAM_PHOTO's files are supplied. */
/* 32%, not 38%: this card renders at BOTH 549px (Popular, 2-up in the full
   container) and 448px (by exam, 2-up beside the 190px rail). At 38% the
   narrower one left ~277px of content, which pushed the three-stat row onto a
   second line. 32% gives it ~305px and the row fits on one line at both
   widths — checked at each, not just the wider one. */
/* Whole card scaled down ~16%, owner's call, 16 Aug 2026 — "boxes look too
   big". Every number below is the old one reduced by roughly that much and
   then RE-VERIFIED against the two constraints their neighbouring comments
   already documented (the 3-stat row width at 448px, the photo's fit against
   the card's two real render widths) — not just shrunk and hoped. */
/* THIS min-height IS WHAT SETS THE CARD'S HEIGHT. The text column is shorter
   than the photo, so the card is `photo + black bar + 2px border` — which is
   why the top/bottom split is tuned from here and from .tsl-sf-split's
   padding, never by adding a height to the card itself.
   Owner tuned this ratio twice on 16 Aug 2026: first to ~84.5% (photo 218px,
   bar 38px), then to **77%**, which is what stands. The relation is
   top = (pct / (1 - pct)) x (black + 2px border) — at 77% that is 3.35x, so
   the black bar still decides total height.
   77% was hit by keeping the CARD'S SIZE and moving only the split — 194 + 56
   + 2 = 252px, against 258px at 84.5% — rather than by shrinking the photo to
   134px, which is what holding the 38px bar would have forced and would have
   dropped the whole card to 174px. The owner had already settled overall card
   size earlier the same day ("boxes look too big"), so a ratio request is
   answered by redistributing, not by resizing the card again. */
.tsl-sf-photo {
  position: relative;
  flex: none;
  width: 32%;
  min-height: 194px;
  background: linear-gradient(135deg, var(--vh-blue-tint) 0%, #dbe1fd 100%) center / cover no-repeat;
  clip-path: polygon(0 0, 100% 0, 88% 100%, 0 100%);
}
/* Anchored to .tsl-sf-card (which is `position: relative`), NOT to
   .tsl-sf-photo — owner's call, 16 Aug 2026, "exclusive button top right of
   the box and thoda sa small". Inside the photo it sat at the top-right of a
   column only 32% of the card wide, so it read as floating near the middle,
   and the photo's clip-path could clip it.
   `z-index: 2` clears the title link's `::after`, a deliberately oversized
   invisible click target (`inset: -100px 0 -60px`, z-index 1) that otherwise
   covers this corner and would swallow the badge. */
.tsl-sf-exclusive {
  position: absolute;
  z-index: 2;
  right: 10px;
  top: 10px;
  background: var(--vh-blue);
  color: #fff;
  font-size: .56rem;
  font-weight: 800;
  letter-spacing: .05em;
  padding: 3px 7px;
  border-radius: 999px;
}

/* Side padding scales with the card, but the 448px-width arithmetic in the
   original comment still has to hold at the new, smaller stat font — checked
   live after this change, not just recalculated on paper. */
.tsl-sf-content { flex: 1 1 auto; min-width: 0; padding: 16px 14px 14px; }
/* Single line, ellipsis-truncated, NOT `min-height`-reserved for a possible
   second line — owner's call, 16 Aug 2026: cards were rendering at two
   different heights because some titles ("UPSC Prelims [10 Online Tests]")
   wrap to a second line at this width and others ("Jee Test [10 Online
   Tests]") do not, and `.tsl-sf-top`'s flex stretch then carried that 21px
   difference into the whole card. Truncating instead of reserving space keeps
   every card at the SHORTER of the two heights rather than the taller. The
   full title survives as a native tooltip (`title=` on the link, in
   test-series-premium.js) and in the accessibility tree regardless of the
   visual clip — text-overflow does not remove text from what a screen reader
   announces. */
.tsl-sf-content h3 { font-size: 1.1rem; font-weight: 800; color: var(--vh-ink); margin-top: 3px; line-height: 1.2; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tsl-sf-content h3 a { position: relative; z-index: 1; color: inherit; }
.tsl-sf-content h3 a::after { content: ""; position: absolute; inset: -100px 0 -60px; }
.tsl-sf-line { font-size: .85rem; color: var(--muted); margin-top: 5px; line-height: 1.4; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* A series with BOTH a manifest line1 AND an owner-written `description`
   (only Talathi has one, 16 Aug 2026) renders TWO .tsl-sf-line paragraphs —
   the second one stacking a whole extra line-height onto the card, which is
   what made Talathi's cards visibly taller than every other exam's. The
   description is not lost: series.html already shows it in full, twice
   (test-series-detail.js), which is the right-sized place for it — this tile
   is a scannable summary, not the place for a second paragraph. Hides
   whichever .tsl-sf-line is second, not "the description" by name, so this
   keeps holding if a future series has a description but no manifest line1. */
.tsl-sf-line + .tsl-sf-line { display: none; }

/* Used to wrap to two lines on a wide stat set (e.g. Tests + Marks + Language
   + a free-count badge together) and let the card grow to fit — "fine BY
   DESIGN", the original comment here said. That stopped being true the
   moment uniform card height became the goal (16 Aug 2026, same pass as the
   h3-truncate and description-hide above): a Talathi card carrying a free
   badge was the one card that still didn't match, one stat badge too many
   for one line. `max-height` + `overflow:hidden` caps it at one line and lets
   whichever badge doesn't fit clip rather than push the card taller — same
   "hide the overflow, don't grow the box" choice as the other two fixes here,
   not a different rule invented for this one case. */
.tsl-sf-stats { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 0; margin-top: 10px; max-height: 20px; overflow: hidden; }
.tsl-sf-stat {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: .76rem;
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
  padding-right: 10px;
  margin-right: 10px;
  border-right: 1px solid var(--border);
}
/* the divider belongs BETWEEN stats, so it comes off the last one on each
   wrapped line too — not just the final element */
.tsl-sf-stat:last-child { border-right: none; margin-right: 0; padding-right: 0; }
.tsl-sf-stat svg { width: 14px; height: 14px; color: var(--vh-blue); flex: none; }
/* an honest stand-in for a series with 0 published papers — never a
   fabricated test count */
.tsl-sf-stat.is-note { color: var(--muted); font-style: italic; font-weight: 500; }

/* Vertical padding is half the ratio equation above — at 11px this bar is
   ~56px, which with a 194px photo puts the top at 77%. It has a hard floor
   (the bar must clear the ₹ price at 1.3rem and a real, tappable button), so
   a LOWER top-percentage is the easy direction and a higher one is the one
   that costs something — at 84.5% this was 5px and the CTA was down to
   28.1px, the smallest it can be and still read as a button. */
.tsl-sf-split {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: auto;
  background: var(--vh-ink);
  padding: 11px 14px;
}
/* line-height, not font-size, is what was making this bar tall: the ₹ figure
   is 1.3rem and inherits the body's ~1.6, so the price block measured 33.3px
   for a 20.8px number. Tightening it to 1.15 buys ~10px of bar height without
   shrinking a single price. */
.tsl-sf-price { display: flex; align-items: baseline; gap: 7px; flex-wrap: wrap; line-height: 1.15; }
.tsl-sf-price b { font-size: 1.3rem; font-weight: 800; color: var(--vh-blue-on-dark); }
.tsl-sf-price small { font-size: .74rem; color: #9aa0ad; font-weight: 600; }
.tsl-sf-price s { font-size: .78rem; color: #7d8296; }
.tsl-sf-off {
  background: rgba(124, 136, 255, .16);
  color: var(--vh-blue-on-dark);
  font-size: .68rem;
  font-weight: 800;
  padding: 3px 8px;
  border-radius: 999px;
  white-space: nowrap;
}
.tsl-sf-price-na { color: #9aa0ad; font-size: .8rem; }
.tsl-sf-cta {
  position: relative;
  z-index: 1;
  flex: none;
  background: var(--vh-blue-fill-dark);
  color: #fff;
  font-size: .84rem;
  font-weight: 700;
  /* Back to 9px now the bar has 56px to spend at top:77% (it was squeezed to
     6px / a 28.1px button at 84.5%, the floor below which this stops reading
     as a button). line-height stays pinned for the same reason as
     .tsl-sf-price: inheriting the body's ~1.6 made a 13px label render 33.5px
     tall on its own, which is what forced that squeeze in the first place. */
  padding: 9px 16px;
  line-height: 1.2;
  border-radius: 8px;
  white-space: nowrap;
  transition: background .2s ease;
}
.tsl-sf-cta:hover { background: var(--vh-blue-on-dark); color: #10121f; }

@media (max-width: 640px) {
  #tslCards, .tsl-exam-group .tsl-cards { grid-template-columns: minmax(0, 1fr); gap: 16px; }
  .tsl-sf-top { flex-direction: column; }
  .tsl-sf-photo { width: 100%; min-height: 130px; clip-path: none; }
  .tsl-sf-split { flex-wrap: wrap; }
}

/* ---------- landing categories ---------- */
.tsl-cat { display: grid; grid-template-columns: 190px minmax(0, 1fr); gap: 18px; margin-top: 18px; }
.tsl-cat-rail { display: flex; flex-direction: column; gap: 2px; border-right: 1px dashed var(--border); padding-right: 12px; }
.tsl-cat-btn { text-align: left; border: 0; background: none; font: inherit; font-size: .82rem; color: var(--text); padding: 6px 10px; border-radius: 7px; cursor: pointer; }
.tsl-cat-btn:hover { background: var(--bg-soft); }
.tsl-cat-btn.is-on { background: var(--primary-light); color: var(--primary); font-weight: 600; }
/* One BLOCK PER EXAM — its own heading and its own card grid. This used to be
   a row of small buttons that filtered the "Popular" section above instead of
   showing anything itself, which meant the section you clicked never listed a
   series. `.tsl-cat-card` was that button and is gone with it. */
.tsl-cat-grid { display: flex; flex-direction: column; gap: 26px; min-width: 0; }
.tsl-exam-group { min-width: 0; }
.tsl-exam-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; padding-bottom: 7px; border-bottom: 1px solid var(--border); }
.tsl-exam-head h3 { font-size: .95rem; font-weight: 700; color: var(--dark); letter-spacing: -.01em; }
.tsl-exam-head span { font-size: .76rem; color: var(--muted); }
/* 420px — TWO cards per row, which is the owner's call (16 Aug 2026) and needs
   arithmetic, not a guess. This grid is the right-hand cell of .tsl-cat, so its
   width is the 1120px container minus the 190px rail and the 18px gap = 912px.
   Two columns therefore need 2 x col + 22px gap <= 912, i.e. col <= 445. The
   460px this started at missed a two-up layout by 30px and every card took a
   full row. 420 clears it with headroom and still degrades to one column on a
   narrower desktop, where two would be cramped anyway.

   Set here at the source rather than in the .tsl-sf-* block above: this
   selector already existed later in the file at equal specificity, so a second
   declaration up there simply lost the cascade. */
.tsl-exam-group .tsl-cards { margin-top: 14px; grid-template-columns: repeat(auto-fill, minmax(420px, 1fr)); }

/* ---------- landing why + faq ---------- */
.tsl-why { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 20px; margin-top: 18px; }
.tsl-why b { display: block; font-weight: 800; font-size: 1.15rem; color: var(--primary); line-height: 1; letter-spacing: -.02em; }
.tsl-why h3 { font-size: .92rem; margin-top: 6px; color: var(--dark); }
.tsl-why p { font-size: .82rem; color: var(--muted); line-height: 1.55; margin-top: 4px; }
.tsl-faq { margin-top: 6px; }
.tsl-faq details { border-bottom: 1px solid var(--border); }
.tsl-faq summary { list-style: none; cursor: pointer; padding: 14px 0; font-size: .9rem; font-weight: 500; color: var(--dark); display: flex; justify-content: space-between; align-items: center; gap: 12px; }
.tsl-faq summary::-webkit-details-marker { display: none; }
.tsl-faq summary::after { content: "+"; color: var(--primary); font-size: 1.1rem; line-height: 1; flex: none; }
.tsl-faq details[open] summary::after { content: "−"; }
.tsl-faq p { padding: 0 0 14px; font-size: .85rem; color: var(--muted); line-height: 1.6; max-width: 70ch; }

/* ---------- catalogue (editorial rows) ---------- */
.tsc-wrap { padding-bottom: 56px; }
.tsc-head { margin: 18px 0 26px; }
.tsc-kicker { display: inline-block; font-size: .68rem; font-weight: 700; letter-spacing: .11em; text-transform: uppercase; color: var(--primary); background: var(--primary-light); border-radius: 4px; padding: 4px 9px; }
.tsc-title { font-weight: 800; font-size: clamp(1.5rem, 3vw, 2rem); line-height: 1.2; letter-spacing: -.02em; color: var(--dark); margin-top: 10px; }
.tsc-lede { max-width: 60ch; margin-top: 8px; color: var(--muted); font-size: .9rem; line-height: 1.6; }
.tsc-rule { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; padding-bottom: 8px; border-bottom: 2px solid var(--dark); margin-top: 34px; }
.tsc-rule h2 { font-weight: 800; font-size: 1.18rem; letter-spacing: -.02em; color: var(--dark); }
.tsc-rule span { font-size: .76rem; color: var(--muted); }
.tsc-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 16px 0; border-bottom: 1px dashed var(--border); }
.tsc-row-main h3 { font-size: 1rem; }
.tsc-row-main h3 a { color: var(--dark); text-decoration: none; }
.tsc-row-main h3 a:hover { color: var(--primary); }
.tsc-row-main p { font-size: .8rem; color: var(--muted); margin-top: 3px; }
.tsc-row-act { display: flex; align-items: center; gap: 12px; flex: none; }
.tsc-price { font-size: 1rem; color: var(--primary); }
.tsc-soon { font-size: .76rem; color: var(--muted); }
.tsc-num { list-style: none; margin-top: 16px; display: grid; gap: 14px; }
.tsc-num li { display: flex; gap: 14px; align-items: flex-start; }
.tsc-num b { font-weight: 800; font-size: 1.05rem; color: var(--primary); line-height: 1.3; letter-spacing: -.02em; flex: none; }
.tsc-num h3 { font-size: .92rem; color: var(--dark); }
.tsc-num p { font-size: .83rem; color: var(--muted); line-height: 1.55; margin-top: 2px; }
.tsc-faq-sec { margin-bottom: 10px; }

/* ---------- detail: shared ---------- */
.tsd-wrap { padding-bottom: 56px; }
.tsd-sub { font-size: .85rem; color: var(--muted); margin-top: 6px; }
.tsd-h2 { font-weight: 800; font-size: 1.08rem; letter-spacing: -.02em; color: var(--dark); margin-top: 26px; padding-bottom: 6px; border-bottom: 1px solid var(--border); }
.tsd-rail { display: flex; flex-direction: column; gap: 14px; }

/* ---------- detail: the pitch ---------- */
.tsd-pitch { display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(260px, 1fr); gap: 30px; margin-top: 18px; align-items: start; }
.tsd-offer { list-style: none; margin-top: 10px; display: grid; gap: 6px; }
.tsd-offer li { font-size: .87rem; color: var(--text); padding-left: 16px; position: relative; }
.tsd-offer li::before { content: "·"; position: absolute; left: 4px; color: var(--primary); font-weight: 700; }
.tsd-about { display: grid; gap: 10px; margin-top: 12px; }
.tsd-about > div { border: 1px solid var(--border); border-radius: 10px; padding: 11px 13px; }
.tsd-about b { font-size: .87rem; color: var(--dark); }
.tsd-about p { font-size: .8rem; color: var(--muted); margin-top: 3px; line-height: 1.5; }
.tsd-buycard { border: 1px solid var(--border); border-radius: 12px; padding: 16px; background: #fff; box-shadow: var(--shadow); text-align: center; }
.tsd-count { display: inline-block; font-size: .68rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }
.tsd-freeline { font-size: .8rem; color: var(--primary); font-weight: 600; margin-top: 4px; }
.tsd-fee { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin: 12px 0 10px; padding-top: 12px; border-top: 1px dashed var(--border); }
.tsd-fee span { font-size: .8rem; color: var(--muted); }
.tsd-fee b { font-size: 1.3rem; color: var(--primary); }
.tsd-buy { width: 100%; }
.tsd-buy-note { font-size: .72rem; color: var(--muted); margin-top: 8px; line-height: 1.45; }
.tsd-note { border: 1px solid var(--border); border-radius: 12px; padding: 13px; background: var(--bg-soft); }
.tsd-note b { font-size: .87rem; color: var(--dark); display: block; }
.tsd-note p { font-size: .79rem; color: var(--muted); margin: 4px 0 9px; line-height: 1.5; }
.tsd-freerow { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 7px 0; border-top: 1px dashed var(--border); font-size: .82rem; }
.tsd-freerow .btn { padding: 4px 12px; font-size: .76rem; }

/* ---------- detail: the workspace ---------- */
.tsd-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin: 18px 0 8px; }
.tsd-owned { font-size: .76rem; font-weight: 700; color: #14804a; background: var(--tint-mint); border-radius: 999px; padding: 6px 13px; flex: none; }
.tsd-cols { display: grid; grid-template-columns: minmax(0, 1.7fr) minmax(250px, 1fr); gap: 26px; margin-top: 18px; align-items: start; }
.tsd-chips { display: flex; flex-wrap: wrap; gap: 7px; padding-bottom: 12px; border-bottom: 2px solid var(--dark); }
.tsd-chip { border: 1px solid var(--border); background: #fff; color: var(--text); border-radius: 999px; padding: 5px 13px; font: inherit; font-size: .77rem; cursor: pointer; }
.tsd-chip.is-on { background: var(--primary); border-color: var(--primary); color: #fff; font-weight: 600; }
.tsd-test { display: grid; grid-template-columns: auto minmax(0, 1fr) auto auto; align-items: center; gap: 12px; padding: 13px 0; border-bottom: 1px dashed var(--border); }
.tsd-test.is-locked { opacity: .72; }
.tsd-test-tags { display: flex; flex-direction: column; gap: 3px; flex: none; }
.tsd-tag { font-size: .62rem; font-weight: 700; letter-spacing: .05em; border-radius: 4px; padding: 3px 6px; background: var(--bg-soft); color: var(--muted); text-align: center; white-space: nowrap; }
.tsd-tag.free { background: var(--primary); color: #fff; }
.tsd-tag.lock { background: #ececf0; color: #84848e; }
.tsd-tag.ranked { background: var(--tint-lav); color: #6b46d6; }
.tsd-test-main h3 { font-size: .93rem; color: var(--dark); }
.tsd-test-main p { font-size: .76rem; color: var(--muted); margin-top: 2px; }
.tsd-score { display: flex; flex-direction: column; align-items: flex-end; flex: none; }
.tsd-score b { font-size: .92rem; color: var(--primary); }
.tsd-score i { font-style: normal; font-size: .7rem; color: var(--muted); }
.tsd-notyet, .tsd-locked-note { font-size: .75rem; color: var(--muted); flex: none; }
.tsd-test-act { display: flex; gap: 7px; flex: none; }
.tsd-test-act .btn { padding: 6px 12px; font-size: .77rem; }
.tsd-lockedbar { margin-top: 14px; padding: 11px 14px; border: 1px dashed var(--border); border-radius: 10px; background: var(--bg-soft); font-size: .82rem; color: var(--muted); }

/* ---------- detail: analytics rail ---------- */
.tsd-panel { border: 1px solid var(--border); border-radius: 12px; padding: 14px; background: #fff; }
.tsd-panel h2 { font-size: .8rem; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: var(--muted); }
.tsd-progress { font-size: .85rem; color: var(--dark); margin-top: 7px; }
.tsd-spark { width: 100%; height: auto; display: block; margin: 8px 0 4px; }
.tsd-metric { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-top: 10px; font-size: .8rem; color: var(--text); }
.tsd-metric b { color: var(--dark); }
.tsd-bar { height: 6px; border-radius: 4px; background: var(--primary-light); margin-top: 4px; overflow: hidden; }
.tsd-bar i { display: block; height: 100%; border-radius: 4px; background: var(--primary); }
.tsd-tiny { font-size: .68rem; color: var(--muted); margin-top: 2px; }
.tsd-empty { font-size: .78rem; color: var(--muted); line-height: 1.5; margin-top: 8px; }

/* ---------- responsive ---------- */
@media (max-width: 900px) {
  .tsd-pitch, .tsd-cols { grid-template-columns: 1fr; }
  .tsl-cat { grid-template-columns: 1fr; }
  .tsl-cat-rail { flex-direction: row; flex-wrap: wrap; border-right: 0; border-bottom: 1px dashed var(--border); padding: 0 0 10px; }
}
@media (max-width: 640px) {
  .tsl-hero { padding: 32px 0 28px; }
  .tsd-test { grid-template-columns: auto minmax(0, 1fr); row-gap: 8px; }
  .tsd-test-tags { flex-direction: row; }
  .tsd-score, .tsd-notyet, .tsd-locked-note, .tsd-test-act { grid-column: 1 / -1; }
  .tsd-score { align-items: flex-start; flex-direction: row; gap: 8px; align-items: baseline; }
  .tsc-row { flex-direction: column; align-items: flex-start; gap: 10px; }
}

/* ---- a paper may be in SEVERAL test series ----
   One checkbox per series, replacing the old single-select dropdown. Ticking
   adds a membership, unticking removes it — this is never "replace the series",
   because access is entitlements/{uid}_{seriesId} and a paper can be sold
   through more than one of them. */
.ad-series-picks {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 190px;
  max-height: 132px;
  overflow-y: auto;
  padding: 6px 8px;
  border: 1px solid var(--border);
  border-radius: 9px;
  background: var(--bg-soft);
}
.ad-series-opt {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 0.78rem;
  line-height: 1.35;
  cursor: pointer;
}
.ad-series-opt input { accent-color: var(--primary); flex: none; }
/* Live papers are read-only here: changing membership would change who can sit
   the paper, in every series, the instant it is written. */
.ad-series-opt.is-locked { opacity: 0.55; cursor: not-allowed; }

/* ---------- test-series: description lines ---------- */
.tsl-desc { font-size: .8rem; color: var(--muted); line-height: 1.5; }
.tsc-desc { font-size: .82rem; color: var(--text); margin-top: 3px; max-width: 62ch; }
.tsd-desc { font-size: .9rem; color: var(--text); line-height: 1.6; margin-top: 8px; max-width: 62ch; }

/* ---------- console: series edit form + paper kind/free ---------- */
/* .ad-price-form is flex-wrap, not a grid — so these size by flex-basis.
   `grid-column: 1 / -1` was silently doing nothing here. */
.ad-f { display: flex; flex-direction: column; gap: 4px; margin-top: 8px; flex: 1 1 190px; }
.ad-f > span { font-size: .74rem; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--muted); }
.ad-f > span i { font-style: normal; font-weight: 400; text-transform: none; letter-spacing: 0; color: var(--muted); opacity: .85; }
.ad-f input[type="text"], .ad-f input[type="date"], .ad-f textarea {
  width: 100%; border: 1px solid var(--border); border-radius: 8px; padding: 8px 10px;
  font: inherit; font-size: .85rem; color: var(--text); background: #fff; }
.ad-f textarea { resize: vertical; min-height: 46px; }
.ad-f-wide { flex: 1 1 100%; }
.ad-f-check { flex-direction: row; align-items: center; gap: 8px; flex: 1 1 100%; }
.ad-f-check span { font-size: .84rem; color: var(--text); text-transform: none; letter-spacing: 0; font-weight: 400; }
.ad-lang { display: flex; flex-wrap: wrap; gap: 12px; }
.ad-lang label { display: inline-flex; align-items: center; gap: 5px; font-size: .84rem; color: var(--text); }
.ad-f-act { display: flex; align-items: center; gap: 12px; margin-top: 12px; flex: 1 1 100%; }

.ad-kind { border: 1px solid var(--border); border-radius: 8px; padding: 6px 8px; font: inherit; font-size: .78rem; background: #fff; color: var(--text); }
.ad-freetog { display: inline-flex; align-items: center; gap: 5px; border: 1px solid var(--border); border-radius: 999px; padding: 5px 11px; font-size: .78rem; color: var(--muted); cursor: pointer; white-space: nowrap; }
.ad-freetog.is-on { border-color: var(--primary); background: var(--primary-light); color: var(--primary); font-weight: 600; }
.ad-freetog input { margin: 0; }

/* ---- pricing: two plans, each with a struck-through "before" price ----
   The cut price is DISPLAY ONLY and is never charged. The server refuses to
   store one that is not strictly higher than the real price, so a "0% OFF"
   badge cannot be rendered from valid data. */

/* the owner's pricing form */
.pf-hint { font-size: .78rem; color: var(--muted); margin-bottom: 10px; }
.pf-plan {
  display: flex;
  align-items: flex-end;
  gap: 10px;
  flex-wrap: wrap;
  padding: 8px 0;
  border-top: 1px solid var(--border);
}
.pf-plan-name { font-size: .8rem; font-weight: 600; min-width: 80px; padding-bottom: 8px; }
.pf-off { font-size: .76rem; font-weight: 700; padding-bottom: 8px; color: var(--muted); }
.pf-off.is-ok { color: var(--q-answered); }
.pf-off.is-bad { color: var(--q-not-answered); font-weight: 600; }

/* the student's card */
.tsc-pricewrap { display: flex; align-items: baseline; gap: 7px; flex-wrap: wrap; }
.tsc-mrp { color: var(--muted); font-size: .86rem; text-decoration: line-through; }
.tsc-off {
  font-size: .7rem;
  font-weight: 700;
  color: var(--q-answered);
  background: #e4f5ec;
  padding: 2px 6px;
  border-radius: 5px;
}
.tsc-per { display: block; width: 100%; font-size: .7rem; color: var(--muted); }

/* The generated buy link, shown read-only in the pricing form. The owner used
   to have to invent this string; it is derived from the series id now. */
.pf-link { font-size: .78rem; color: var(--muted); margin: 8px 0 4px; }
.pf-link code {
  display: inline-block;
  margin-left: 8px;
  padding: 3px 8px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg-soft);
  color: var(--text);
  font-size: .76rem;
  user-select: all;
}

/* Plan pricing on the premium list and the series detail page. The struck
   figure and its percentage come from the server, so no surface can invent a
   discount the catalogue does not have. */
.tsl-pricewrap { display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; }
.tsl-mrp { color: var(--muted); font-size: .84rem; text-decoration: line-through; }
.tsl-off {
  font-size: .68rem; font-weight: 700; color: var(--q-answered);
  background: #e4f5ec; padding: 2px 6px; border-radius: 5px;
}
.tsl-per { display: block; width: 100%; font-size: .7rem; color: var(--muted); }

.tsd-plan {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 12px 0; border-top: 1px solid var(--border);
}
.tsd-plan:first-of-type { border-top: 0; }
.tsd-plan-price { display: flex; align-items: baseline; gap: 7px; }
.tsd-plan-price s { color: var(--muted); font-size: .9rem; }
.tsd-plan-price b { font-size: 1.35rem; letter-spacing: -.5px; }
.tsd-off {
  font-size: .7rem; font-weight: 700; color: var(--q-answered);
  background: #e4f5ec; padding: 2px 7px; border-radius: 5px;
}
.tsd-plan-label { font-size: .8rem; color: var(--muted); }
.tsd-plan .tsd-buy { margin-left: auto; }

/* =========================================================
   ONE TEST SERIES — the header band and its price card.
   Built to the owner's Claude Design mock. Everything on it comes off a real
   field: the chips are counted from the papers on the page below, and the
   prices and discounts are computed server-side by planOf() so this page and
   the catalogue card can never disagree.
   ========================================================= */
.tsd-band {
  display: flex;
  gap: 24px;
  align-items: flex-start;
  flex-wrap: wrap;
  background: var(--primary-light);
  border-radius: var(--radius);
  padding: 22px 24px;
  margin-bottom: 22px;
}
.tsd-band-main { flex: 1 1 380px; min-width: 0; }
.tsd-band .tsc-title { margin: 0 0 10px; }

.tsd-hchips { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 10px; }
.tsd-hchip {
  font-size: .74rem;
  font-weight: 600;
  padding: 4px 11px;
  border-radius: 999px;
  border: 1px solid rgba(26, 46, 240, .25);
  background: #fff;
  color: var(--primary-dark);
}
.tsd-hchip.is-free { background: var(--q-answered); border-color: var(--q-answered); color: #fff; }
/* The header band is the first screen a buyer sees. It used to be a title, two
   chips and a one-line "What you get", which read as half-finished. It now
   carries a kicker, a lead sentence, a spec strip and four concrete claims. */
.tsd-band-kicker {
  display: block; font-size: .7rem; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--primary);
}
.tsd-band .tsd-band-kicker + .tsc-title { margin-top: 6px; }
.tsd-band-lead {
  font-size: .95rem; line-height: 1.65; color: var(--text);
  max-width: 62ch; margin: 0 0 14px;
}
.tsd-gets { margin: 16px 0 0; max-width: none; }
.tsd-gets-head {
  display: block; font-size: .72rem; font-weight: 800; letter-spacing: .1em;
  text-transform: uppercase; color: var(--muted); margin-bottom: 10px;
}
/* 260px, not 240: at 240 the four cards fell 3-across and one orphaned onto a
   second row. This gives a balanced 2x2 in the band's width. */
.tsd-getgrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 10px; }
.tsd-get {
  background: rgba(255, 255, 255, .72); border: 1px solid rgba(255, 255, 255, .9);
  border-radius: 11px; padding: 12px 13px;
}
.tsd-get b { display: block; font-size: .86rem; font-weight: 700; color: var(--dark); margin-bottom: 3px; }
.tsd-get p { font-size: .79rem; line-height: 1.55; color: var(--muted); }
.tsd-get p b { display: inline; font-size: inherit; color: var(--text); margin: 0; }

@media (max-width: 640px) {
  .tsd-getgrid { grid-template-columns: 1fr; }
  .tsd-band-lead { font-size: .9rem; }
}

.tsd-pricecard {
  flex: 0 0 300px;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 13px;
  padding: 16px 18px;
  box-shadow: var(--shadow);
}
.tsd-pricecard.is-owned { text-align: center; }
.tsd-buyrow { padding: 10px 0; border-top: 1px solid var(--border); }
.tsd-buyrow:first-child { border-top: 0; padding-top: 0; }
.tsd-buyprice { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.tsd-buyprice s { color: var(--muted); font-size: .92rem; }
.tsd-buyprice b { font-size: 1.5rem; letter-spacing: -.6px; color: var(--primary); }
.tsd-buyper { display: block; font-size: .74rem; color: var(--muted); margin: 2px 0 9px; }
.tsd-buyrow .btn { width: 100%; justify-content: center; }
.tsd-tryfree { font-size: .76rem; color: var(--primary); text-align: center; margin: 10px 0 0; }
.tsd-until { font-size: .78rem; color: var(--muted); margin: 6px 0 0; }

/* "113 locked. Buy this series to unlock all." */
.tsd-lockedbar {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  margin-top: 14px;
  padding: 13px 16px;
  border: 1px dashed var(--border);
  border-radius: 12px;
  background: var(--bg-soft);
  font-size: .84rem;
  color: var(--muted);
}
.tsd-lockedbar b { color: var(--text); }
.tsd-lockedbar .btn { margin-left: auto; }

.tsd-why { margin: 0; padding-left: 18px; font-size: .82rem; color: var(--muted); }
.tsd-why li { margin-bottom: 6px; }
.tsd-analysis-empty .tsd-empty { margin: 0; }

/* The sample analysis shown before anyone buys. Every number in it is invented,
   so it is styled to be READ AS A SAMPLE at a glance and never mistaken for the
   visitor's own figures: a tinted panel, a dashed edge, an "Example" badge, and
   bars muted off the live --primary. The badge and the closing line are load
   bearing — do not drop them to tidy the panel up. */
.tsd-sample { background: var(--bg-soft); border-style: dashed; }
.tsd-sample-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.tsd-sample-tag {
  flex: none; font-size: .6rem; font-weight: 800; letter-spacing: .1em; text-transform: uppercase;
  color: var(--muted); background: #fff; border: 1px solid var(--border);
  border-radius: 999px; padding: 2px 8px;
}
.tsd-sample-sub {
  margin: 14px 0 2px; font-size: .8rem; font-weight: 700; letter-spacing: .07em;
  text-transform: uppercase; color: var(--muted);
}
.tsd-sample .tsd-bar i { background: var(--muted); opacity: .45; }
.tsd-sample .tsd-spark { opacity: .7; }
.tsd-sample-note {
  margin-top: 12px; padding-top: 10px; border-top: 1px dashed var(--border);
  font-size: .74rem; line-height: 1.5; color: var(--muted);
}
.tsd-sample-note b { color: var(--text); }

/* ---------- the long page below the test list ---------- */
.tsd-sec { margin-top: 42px; }
.tsd-sec-head { padding-bottom: 10px; border-bottom: 2px solid var(--dark); }
.tsd-sec-head h2 { font-weight: 800; font-size: 1.2rem; letter-spacing: -.02em; color: var(--dark); }

/* "Show N more" under the test list */
.tsd-more { display: flex; justify-content: center; margin-top: 16px; }
.tsd-more .btn { min-width: 220px; }

/* why take this series */
.tsd-whygrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 18px; margin-top: 20px; }
.tsd-whycard { border: 1px solid var(--border); border-radius: 12px; padding: 16px; background: #fff; }
.tsd-whycard b { display: block; font-size: .8rem; font-weight: 800; color: var(--primary); letter-spacing: .06em; }
.tsd-whycard h3 { margin: 6px 0 6px; font-size: .96rem; font-weight: 700; color: var(--dark); letter-spacing: -.01em; }
.tsd-whycard p { font-size: .83rem; color: var(--muted); line-height: 1.6; }
.tsd-whycard p b { display: inline; font-size: inherit; color: var(--text); letter-spacing: 0; }

/* the detailed description */
.tsd-prose { margin-top: 18px; }
.tsd-prose p { font-size: .9rem; color: var(--text); line-height: 1.75; max-width: 78ch; margin-bottom: 14px; }
.tsd-prose h3 { margin: 26px 0 10px; font-size: 1.02rem; font-weight: 700; color: var(--dark); letter-spacing: -.01em; }
.tsd-steps { margin: 0 0 14px; padding-left: 20px; max-width: 78ch; }
.tsd-steps li { font-size: .88rem; color: var(--text); line-height: 1.7; margin-bottom: 7px; }

/* Wide tables must scroll INSIDE their own box — the page body must never
   scroll sideways on a phone. */
.tsd-tablewrap { overflow-x: auto; border: 1px solid var(--border); border-radius: 12px; }
.tsd-table { width: 100%; border-collapse: collapse; min-width: 460px; }
.tsd-table th, .tsd-table td { text-align: left; padding: 12px 14px; font-size: .86rem; border-bottom: 1px solid var(--border); vertical-align: top; }
.tsd-table thead th { background: var(--bg-soft); font-weight: 700; color: var(--dark); font-size: .82rem; }
.tsd-table tbody tr:last-child td { border-bottom: 0; }
.tsd-table td:first-child { font-weight: 600; color: var(--dark); width: 34%; }
.tsd-table td { color: var(--muted); line-height: 1.6; }
.tsd-table td b { color: var(--text); }

@media (max-width: 640px) {
  .tsd-sec { margin-top: 32px; }
  .tsd-more .btn { min-width: 0; width: 100%; }
}

@media (max-width: 760px) {
  .tsd-band { padding: 18px 16px; }
  .tsd-pricecard { flex: 1 1 100%; }
  .tsd-lockedbar .btn { margin-left: 0; width: 100%; justify-content: center; }
}

/* ===================================================================
   PYQ VAULT  (.pv-*)  — the redesigned builder shell.
   Renamed from "Ultimate PYQs" on the SURFACE only: the entitlement id
   `ultimate-pyqs` and the checkout slugs are payment keys and are unchanged,
   because renaming those would revoke access for everyone who has paid.
   The inner `.pyq-*` blocks (format summary, chapter picker, status) are kept
   as they were — ultimate-pyqs.js renders into them by id.
   =================================================================== */

/* The vault band (.pv-band, text + year-strip) was replaced by the
   Independence Day .hero-banner poster on 16 Aug 2026 — see ultimate-pyqs.html. */

/* ---- steps ---- */
.pv-form { display: flex; flex-direction: column; gap: 26px; }
.pv-step { border-top: 1px dashed var(--border); padding-top: 20px; }
.pv-step:first-child { border-top: 0; padding-top: 0; }
.pv-step-head {
  display: flex; align-items: center; gap: 10px; margin-bottom: 14px;
  font-size: .76rem; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; color: var(--muted);
}
.pv-step-head i {
  display: grid; place-items: center; width: 22px; height: 22px; flex: none;
  background: var(--primary); color: #fff; border-radius: 50%;
  font-size: .72rem; font-style: normal; font-weight: 800;
}

/* The original <select> is kept and driven by the chips, so no builder logic
   changed. Hidden accessibly rather than display:none, which would drop it
   from the form and from assistive tech entirely. */
.pv-sr-select { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }

.pv-chips { display: flex; gap: 9px; flex-wrap: wrap; }
.pv-chip {
  font: inherit; font-size: .86rem; font-weight: 600; cursor: pointer;
  background: #fff; color: var(--text); border: 1px solid var(--border);
  border-radius: 999px; padding: 9px 20px; transition: border-color .15s, background .15s, color .15s;
}
.pv-chip:hover { border-color: var(--primary); }
.pv-chip.is-on { background: var(--primary); border-color: var(--primary); color: #fff; }

/* ---- the three practice cards ---- */
.pv-modes { display: grid; grid-template-columns: repeat(auto-fit, minmax(215px, 1fr)); gap: 14px; border: 0; padding: 0; margin: 0; }
.pv-mode {
  position: relative; display: block; cursor: pointer;
  border: 1.5px solid var(--border); border-radius: 14px; padding: 16px 16px 14px;
  background: #fff; transition: border-color .15s, box-shadow .15s;
}
.pv-mode:hover { border-color: var(--primary); }
.pv-mode.selected { border-color: var(--primary); box-shadow: 0 0 0 3px var(--primary-light); }
.pv-mode input { position: absolute; opacity: 0; pointer-events: none; }
.pv-mode-tick {
  display: block; width: 18px; height: 18px; border-radius: 5px;
  border: 1.5px solid var(--border); margin-bottom: 12px;
}
.pv-mode.selected .pv-mode-tick { background: var(--primary); border-color: var(--primary); }
.pv-mode.selected .pv-mode-tick::after {
  content: ""; display: block; width: 4px; height: 8px; margin: 2px auto 0;
  border: solid #fff; border-width: 0 2px 2px 0; transform: rotate(45deg);
}
.pv-mode strong { display: block; font-size: 1rem; font-weight: 700; color: var(--dark); }
.pv-mode-sub { display: block; font-size: .8rem; color: var(--muted); margin-top: 3px; line-height: 1.5; }
.pv-mode-spec {
  display: block; margin-top: 12px; text-align: center;
  font-size: .76rem; font-weight: 600; color: var(--primary);
  background: var(--primary-light); border-radius: 8px; padding: 7px 10px;
}

.pv-note { font-size: .78rem; color: var(--muted); margin-top: 12px; }
.pv-go { width: 100%; padding: 14px; font-size: .95rem; }

/* ---- what every paper comes with ---- */
.pv-trust {
  display: flex; flex-wrap: wrap; gap: 8px 26px; justify-content: center;
  margin: 30px 0 8px; padding: 16px; list-style: none;
  border-top: 1px solid var(--border); border-bottom: 1px solid var(--border);
}
.pv-trust li { font-size: .82rem; color: var(--muted); }
.pv-trust li::before { content: "✓"; color: var(--q-answered); font-weight: 800; margin-right: 7px; }

@media (max-width: 640px) {
  .pv-trust { flex-direction: column; align-items: flex-start; gap: 7px; }
}

/* PYQ Vault paywall — the plans now carry a struck-through original price, and
   the note explains that JEE and NEET are bought separately (same price, two
   products). Scoped to .pyq-plan so nothing else picks up the strike. */
.pyq-plan strong s { color: #8aa398; font-weight: 500; font-size: .82rem; margin-right: 5px; }

/* =========================================================================
   HOME PAGE — the 14 Aug 2026 redesign  (§34)

   Built from the owner's Claude Design canvas (Vidhyabhavan.dc.html). Every
   rule is prefixed `vh-` and the page-level ones are scoped under
   `body.vh-home`, because style.css is one stylesheet shared by ~52 marketing
   pages — the same reason `.tp-*` sits under `.tp-panel` and `.ac-*` under
   `body.ac-body`.

   The canvas is a fixed 1440px artboard with absolutely-positioned pieces.
   Those are re-expressed as flow/grid layout here; the display type is
   clamp()ed so nothing overflows a phone. The canvas's IBM Plex Mono labels
   ("banner", "exam art", "product visual") are wireframe chrome, not design.
   ========================================================================= */

/* Barlow is the canvas's body face. Poppins stays SECOND rather than being
   dropped: it is what carries the Devanagari subset, and Noto stays last, so
   this page keeps the same script coverage as every other one even though it
   has no Marathi on it today. */
body.vh-home {
  font-family: "Barlow", "Poppins", "Noto Sans Devanagari", "Segoe UI", system-ui, sans-serif;
}

.vh-wrap { width: min(var(--vh-max), 92%); margin-inline: auto; }

.vh-h2 {
  font-size: clamp(1.35rem, 2.1vw, 1.875rem);
  font-weight: 700;
  line-height: 1.25;
  color: var(--vh-ink);
}
/* the design underlines the blue words in yellow rather than colouring them */
.vh-h2 .vh-mark { color: var(--vh-blue); border-bottom: 4px solid #ffd233; }

/* The "artwork not supplied yet" placeholder classes (vh dash slot, and its
   on-dark variant) were removed here 16 Aug 2026 — their only use, the
   reviews section's student photo, became a real <img> the same day, and
   scripts/verify-home.js fails hard on styled-but-unused classes rather than
   warning. NOTE: that checker regex-scans this file's raw text for `.vh-`,
   comments included — writing the actual class name here with its leading
   dot would make this very sentence trip the same check. It was ~15 lines;
   if another not-yet-supplied slot needs this treatment, rewrite it rather
   than leave a permanently-failing check as the cost of keeping it "for
   later". */

/* Copy the owner still has to write. Marked rather than invented: the design
   canvas carried named students with percentiles and a placement claim, and
   nothing in this system holds a single student outcome (§8 dropped percentile
   for the same reason). Visible on purpose — a silent empty slot is how a
   placeholder ships to production unnoticed. */
.vh-todo {
  font-style: italic;
  opacity: 0.62;
  text-decoration: underline dotted;
  text-underline-offset: 3px;
  font-weight: 500;
}

/* ---------- 1. the three exam tiers under the banner ---------- */
.vh-tiers {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 18px;
  padding: 22px 0;
}
.vh-tier {
  display: flex;
  align-items: center;
  gap: 12px;
  background: #fff;
  border: 1px solid #e6e6ea;
  border-radius: 12px;
  box-shadow: 0 6px 18px rgba(20, 30, 60, 0.08);
  padding: 14px 16px;
  transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
}
.vh-tier:hover {
  transform: translateY(-2px);
  border-color: #cfd6ee;
  box-shadow: 0 10px 24px rgba(20, 30, 60, 0.13);
}
/* The canvas drew a 32px tinted icon tile before each label. Removed at the
   owner's request (14 Aug 2026) — the label carries the card on its own. */
.vh-tier-name { flex: 1; font-size: 1rem; font-weight: 700; line-height: 1.2; }
/* .vh-tier-go — the circular arrow "button" — removed at the owner's request
   (16 Aug 2026): the three cards are not links, so it pointed at nothing. Its
   ruleset and the `.vh-tier:hover .vh-tier-go` hover rule are both gone along
   with the markup in index.html. */

/* ---------- 2. What's Trending — REMOVED (owner, 16 Aug 2026) ----------
   Section and its markup are gone from index.html; this block went with it.
   Was the classes "vh-trend", "vh-trend-h" and "vh-trend-car". Written here
   WITHOUT a period before the class name on purpose: verify-home.js's class
   scan is a plain regex over this file, not a real CSS parser, so a dot
   immediately before a vh-prefixed word reads as a live selector even inside
   a comment. */

/* ---------- 3. What's new — the two product cards ---------- */
.vh-new { padding: 52px 0 44px; }
.vh-new-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 22px;
  margin-top: 22px;
}
.vh-pcard {
  position: relative;
  overflow: hidden;
  /* No min-height: the two cards carry near-identical bullet-list length (5
     wrapped lines each), and `.vh-new-grid` never overrides Grid's default
     align-items:stretch, so the row already equalises both cards to whichever
     is taller. The fixed 260px floor was taller than either card's natural
     content and was the entire source of the dead gap the owner flagged.
     padding-bottom is widened to reserve room for the CTA, which is now
     absolutely positioned and out of flow — see .vh-pcard-cta below. */
  border-radius: 10px;
  background: var(--vh-ink);
  color: #fff;
  padding: 24px 28px 64px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}
.vh-pcard-brand {
  position: absolute;
  right: 20px;
  top: 16px;
  font-size: 0.94rem;
  font-weight: 700;
}
/* No padding-right any more: it existed only to keep the title clear of the
   "product visual" block, which the owner removed (14 Aug 2026). max-width
   still keeps the title off the brand label in the top-right corner. */
.vh-pcard-t {
  font-size: 1.25rem;
  font-weight: 700;
  font-style: italic;
  line-height: 1.35;
  max-width: 280px;
}
.vh-pcard-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 14px;
  max-width: 300px;
}
.vh-pcard-list li {
  font-size: 0.75rem;
  font-weight: 600;
  color: #e4e5ea;
  line-height: 1.45;
}
.vh-pcard-list li::before { content: "\2605\00a0"; }
.vh-pcard-cta {
  display: inline-block;
  background: var(--vh-blue-fill-dark);
  color: #fff;
  border-radius: 6px;
  padding: 8px 18px;
  font-size: 0.82rem;
  font-weight: 600;
  transition: background 0.2s ease;
  /* Pinned to the same right inset as .vh-pcard-brand (right:20px) so the
     button's right edge lines up with "VidhyaBhavan" above it — the owner's
     ask. `bottom:20px` (not 0) lifts it off the card's floor rather than
     sitting flush against the edge. Absolute + out of flow, so it no longer
     needs the list's height to "push" it anywhere; the dead gap that used to
     sit above it is gone along with the flex trick that caused it. */
  position: absolute;
  right: 20px;
  bottom: 20px;
}
/* hover goes LIGHTER, not darker — on a near-black card, darkening a button is
   the direction that makes it disappear */
.vh-pcard-cta:hover { background: var(--vh-blue-on-dark); color: #10121f; }
/* ---------- 4. the CBT headline + enquiry form ---------- */
.vh-cbt {
  display: grid;
  grid-template-columns: 1.15fr 1fr;
  gap: 60px;
  align-items: center;
  padding: 60px 0;
}
.vh-cbt-title {
  font-family: var(--vh-cond);
  font-weight: 800;
  font-size: clamp(2rem, 4.2vw, 3.5rem);
  line-height: 1.12;
  color: #111;
}
.vh-cbt-title span { color: var(--vh-blue); }
.vh-rule { width: 180px; height: 3px; background: #111; margin: 16px 0 14px; }

.vh-form {
  background: #fff;
  border-radius: 20px;
  box-shadow: 0 8px 26px rgba(0, 0, 0, 0.10);
  padding: 22px 26px 26px;
}
.vh-form h2 {
  text-align: center;
  font-family: var(--vh-cond);
  font-weight: 800;
  font-size: clamp(1.2rem, 1.9vw, 1.5rem);
  color: #111;
  margin-bottom: 14px;
}
.vh-form .form-row { margin-bottom: 11px; }
.vh-form .form-row label {
  font-family: var(--vh-cond);
  font-weight: 600;
  font-size: 0.86rem;
  color: #33363d;
}
.vh-form .form-row label span { color: #d0021b; }
.vh-form .form-row input,
.vh-form .form-row select {
  height: 36px;
  padding: 0 11px;
  border: 1px solid #d8dae1;
  border-radius: 8px;
  font-size: 0.82rem;
}
.vh-form .form-row select { padding-right: 8px; }
.vh-form .form-row input:focus,
.vh-form .form-row select:focus {
  border-color: var(--vh-blue);
  box-shadow: 0 0 0 3px rgba(26, 46, 240, 0.15);
}
.vh-form-row2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}
.vh-form-row2 .form-row { margin-bottom: 2px; }
.vh-form .btn {
  display: block;
  width: 100%;
  background: var(--vh-blue);
  color: #fff;
  text-align: center;
  border-radius: 8px;
  padding: 10px 20px;
  font-family: var(--vh-cond);
  font-weight: 700;
  font-size: 0.96rem;
  margin-top: 6px;
}
.vh-form .btn:hover { background: var(--vh-blue-dark); }

/* ---------- 5. Join the test series ---------- */
.vh-join { padding: 74px 0; text-align: center; }
.vh-join-h { font-size: clamp(1.5rem, 2.6vw, 2.125rem); font-weight: 800; }
.vh-join-h span { color: var(--vh-blue); font-style: italic; text-decoration: underline; }
.vh-join-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 24px;
  margin-top: 34px;
  text-align: left;
}
/* The grid's children are now real .tsl-sf-card elements (js/homepage-join.js
   + js/test-series-card.js) — see style.css's .tsl-sf-* rules. No .vh-join-
   card/-top/-exam/-sub/-body/-list/-cta rules remain; they only ever styled
   the hand-typed static cards this section replaced on 16 Aug 2026. */

/* ---------- 7b. book your free demo (16 Aug 2026) ---------- */
.vh-bydm-band { background: var(--bg-soft); }
/* Caps at 1040px rather than riding .vh-wrap's 1352px: two 1fr columns that
   wide left the copy and the art marooned at opposite ends with ~270px of dead
   air between them. `auto` on the art column sizes it to the image instead of
   to half the row, so the gap is the gap and nothing else. */
.vh-bydm {
  width: min(1040px, 92%);
  margin-inline: auto;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: clamp(24px, 4vw, 56px);
  align-items: center;
  padding: 48px 0;
}
.vh-bydm-h {
  font-size: clamp(1.6rem, 3vw, 2.4rem);
  font-weight: 800;
  color: var(--vh-ink);
  line-height: 1.25;
}
.vh-bydm-h span { color: var(--vh-blue); border-bottom: 4px solid var(--accent-soft); }
.vh-bydm-sub { margin: 14px 0 26px; color: var(--muted); font-size: 1rem; }
/* `margin-left: auto`, NOT `text-align: right` on the parent: the global
   `img, svg { display: block }` (§base) makes this a block box, and text-align
   cannot move one — it sat at the left of its column looking marooned. */
.vh-bydm-art { text-align: right; }
.vh-bydm-art img { margin-left: auto; max-width: 100%; max-height: 360px; width: auto; height: auto; }

/* ---- book-a-free-demo modal: course -> language -> details, one form ----
   Same overlay/panel shell as .tp-modal (style.css §"modals"), given its own
   prefix rather than reused directly so this marketing feature and the test
   player don't share class names for two unrelated things. */
.bydm-modal-wrap {
  position: fixed;
  inset: 0;
  background: rgba(20, 25, 43, 0.55);
  display: grid;
  place-items: center;
  z-index: 200;
  padding: 22px;
}
.bydm-modal {
  position: relative;
  background: #fff;
  border-radius: 18px;
  padding: 30px;
  width: min(500px, 100%);
  max-height: 90vh;
  overflow-y: auto;
}
.bydm-close {
  position: absolute;
  top: 14px;
  right: 14px;
  width: 32px;
  height: 32px;
  border: none;
  border-radius: 50%;
  background: var(--bg-soft);
  color: var(--muted);
  font-size: 1.3rem;
  line-height: 1;
  cursor: pointer;
}
.bydm-close:hover { background: var(--border); }

.bydm-wz { display: flex; align-items: center; justify-content: center; gap: 8px; margin-bottom: 22px; }
.bydm-wz-step { display: flex; align-items: center; gap: 6px; font-size: 0.76rem; font-weight: 600; color: var(--muted); }
.bydm-wz-num {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-size: 0.7rem;
  font-weight: 700;
  background: var(--border);
  color: var(--muted);
}
.bydm-wz-step.is-on { color: var(--text); }
.bydm-wz-step.is-on .bydm-wz-num { background: var(--vh-blue); color: #fff; }
.bydm-wz-step.is-done .bydm-wz-num { background: var(--vh-blue-tint); color: var(--vh-blue); }
.bydm-wz-line { width: 26px; height: 2px; background: var(--border); border-radius: 2px; }
.bydm-wz-line.is-done { background: var(--vh-blue); }

.bydm-form h2 {
  font-family: "Poppins", "Noto Sans Devanagari", "Segoe UI", system-ui, sans-serif;
  font-weight: 700;
  font-size: 1.2rem;
  white-space: nowrap;
  text-align: center;
  margin-bottom: 6px;
}
.bydm-step-sub { text-align: center; color: var(--muted); font-size: 0.88rem; margin-bottom: 20px; }

.bydm-choices { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; }
.bydm-choice {
  padding: 10px 18px;
  border: 1.5px solid var(--border);
  border-radius: 999px;
  background: #fff;
  color: var(--text);
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
  transition: border-color 0.2s ease, background 0.2s ease, color 0.2s ease;
}
.bydm-choice:hover { border-color: var(--vh-blue); }
.bydm-choice.is-selected { border-color: var(--vh-blue); background: var(--vh-blue); color: #fff; }

.bydm-back {
  display: block;
  margin: 18px auto 0;
  background: none;
  border: none;
  color: var(--muted);
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
}
.bydm-back:hover { color: var(--text); }
.bydm-form .btn { display: block; width: 100%; text-align: center; margin-top: 4px; }

.bydm-success-actions { display: flex; flex-direction: column; gap: 10px; margin-top: 16px; }
.bydm-quit {
  display: block;
  width: 100%;
  padding: 10px 20px;
  border: 1.5px solid var(--border);
  border-radius: 10px;
  background: #fff;
  color: var(--text);
  font-weight: 600;
  font-size: 0.9rem;
  cursor: pointer;
  text-align: center;
}
.bydm-quit:hover { border-color: var(--vh-blue); color: var(--vh-blue); }

/* ---------- 7. the student voice band ----------
   Built to take a PHOTO behind it, not a flat colour. Set the image on the
   section and everything else follows:

       <section class="vh-voice" style="--vh-voice-photo: url('/images/x.webp')">

   ⚠ ROOT-RELATIVE, with the leading slash. A relative url() in a custom
   property resolves against THIS stylesheet, so 'images/x.webp' is fetched as
   /css/images/x.webp and 404s silently — the section simply stays black.

   ⚠ THE SCRIM IS NOT DECORATION — it is what keeps the text legible over an
   image nobody has seen yet. A photo has bright pixels, and white/blue text on
   a bright pixel is unreadable. Working out the minimum black alpha needed for
   the WORST case (a pure-white pixel underneath):

       white body text at 4.5:1 ......... alpha >= 0.54
       #7c88ff name at 3:1 (large) ...... alpha >= 0.76

   So the text half of the gradient never goes below 0.86 — that covers the
   worst pixel a photo can contain, with headroom. The image side is lighter
   (0.52) because only the framed photo sits there, no text. Do not lighten the
   right-hand stops to "show the picture better": the picture is a texture here,
   the words are the content.

   SHRUNK 17 Aug 2026 (owner, "decrease it size"): section padding 54/74 -> 36/52,
   photo 340px -> 250px, quote clamp topped out at 1.95rem -> 1.3rem. The layout
   is unchanged — this is the same band, just smaller. */
.vh-voice {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  background-color: #0b0b0d;
  /* the extra bottom padding is the watermark's lane — without it the ghosted
     text runs under the experience chips */
  padding: 36px 0 52px;
}
.vh-voice::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  /* gradient first = painted ON TOP of the photo layer below it */
  background-image:
    linear-gradient(to right,
      rgba(0, 0, 0, 0.52) 0%,
      rgba(0, 0, 0, 0.74) 28%,
      rgba(0, 0, 0, 0.86) 46%,
      rgba(0, 0, 0, 0.9) 100%),
    var(--vh-voice-photo, none);
  background-size: cover;
  background-position: center;
}
.vh-voice > .vh-wrap { position: relative; z-index: 2; }

/* "15+ years of legacy", ghosted into the corner. Real copy, so it is not
   aria-hidden — a screen reader should still get the claim. */
.vh-voice-mark {
  position: absolute;
  z-index: 1;
  right: clamp(12px, 3vw, 44px);
  bottom: clamp(6px, 1.4vw, 18px);
  margin: 0;
  font-family: var(--vh-cond);
  font-weight: 800;
  font-size: clamp(1.1rem, 3.6vw, 2.9rem);   /* was clamp(1.25rem, 4.4vw, 3.6rem) */
  line-height: 1;
  letter-spacing: -0.02em;
  white-space: nowrap;
  color: rgba(255, 255, 255, 0.085);
  pointer-events: none;
  user-select: none;
}
.vh-voice-grid {
  display: grid;
  grid-template-columns: 1fr 1.5fr;
  gap: 40px;   /* was 48px */
  align-items: center;
}
.vh-voice-photo { position: relative; min-height: 250px; border-radius: 14px; }   /* was 340px */
img.vh-voice-photo {
  display: block;
  width: 100%;
  height: 250px;   /* was 340px */
  object-fit: cover;
  border: 1px solid rgba(255, 255, 255, 0.16);
}
.vh-voice-eyebrow {
  font-size: 0.72rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #8a8f9c;
}
.vh-voice-quote {
  font-size: clamp(0.95rem, 1.5vw, 1.3rem);   /* was clamp(1.05rem, 2.2vw, 1.95rem) */
  line-height: 1.55;
  color: #fff;
  margin-top: 14px;
  font-weight: 500;
  text-wrap: pretty;
}
.vh-voice-name {
  font-family: var(--vh-cond);
  font-weight: 800;
  font-size: clamp(1.05rem, 1.5vw, 1.35rem);   /* was clamp(1.2rem, 1.8vw, 1.65rem) */
  color: var(--vh-blue-on-dark);
  margin-top: 14px;
}
/* Every experience is stacked into ONE grid cell, so the stage is always as
   tall as the LONGEST quote and nothing below it moves when the quote changes.
   A plain display:none swap bounced the chips every seven seconds; a hardcoded
   min-height would fix it at one viewport width and break at the next, while
   this self-sizes at every width for free.

   `visibility` rather than `display` because a visibility:hidden item still
   occupies its cell (which is what does the sizing) while staying out of the
   accessibility tree and the tab order. */
.vh-voice-stage { display: grid; }
.vh-voice-item {
  grid-area: 1 / 1;
  visibility: hidden;
  opacity: 0;
  transition: opacity 0.45s ease;
}
.vh-voice-item.is-on { visibility: visible; opacity: 1; }
.vh-voice-who { display: block; }

.vh-voice-chips { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; }
/* a <button>, so it needs the UA styles knocked off. The avatar disc that used
   to sit at the left of each chip was dropped 17 Aug 2026 (owner) — the chips
   are name-only now, so the padding is even on both sides again. */
.vh-voice-chip {
  display: flex;
  align-items: center;
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 12px;
  padding: 8px 14px;
  font: inherit;
  text-align: left;
  color: inherit;
  cursor: pointer;
  transition: background 0.2s ease, border-color 0.2s ease;
}
.vh-voice-chip:hover,
.vh-voice-chip:focus-visible {
  background: rgba(255, 255, 255, 0.14);
  border-color: rgba(255, 255, 255, 0.34);
}
.vh-voice-chip b { display: block; font-size: 0.86rem; font-weight: 600; color: #fff; }
.vh-voice-more {
  display: flex;
  align-items: center;
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 12px;
  padding: 0 18px;
  font-size: 0.86rem;
  font-weight: 600;
  color: #fff;
}

/* ---------- 8. the colleges marquee ---------- */
.vh-colleges { padding: 74px 0 78px; text-align: center; }
.vh-colleges-h { font-size: clamp(1.6rem, 3vw, 2.5rem); font-weight: 800; }
.vh-colleges-h span { color: var(--vh-blue); }
.vh-colleges-sub { font-size: 1.06rem; color: #5b6070; margin-top: 8px; }
.vh-colleges-sub b { color: var(--vh-ink); }

.vh-marquee { overflow: hidden; margin-top: 34px; }
.vh-marquee-track {
  display: flex;
  gap: 44px;
  width: max-content;
  animation: vh-marquee 34s linear infinite;
}
.vh-marquee:hover .vh-marquee-track { animation-play-state: paused; }
@keyframes vh-marquee {
  from { transform: translateX(-50%); }
  to   { transform: translateX(0); }
}
.vh-college {
  display: flex;
  align-items: center;
  gap: 12px;
  flex: none;
}
/* Real crest images (16 Aug 2026) — was a plain "IIT"/"AII" text abbreviation
   in a tinted circle; owner asked for the institutions' actual logos.
   `overflow:hidden` is what actually clips a square <img> to the circle —
   border-radius alone does nothing to child content without it.
   `background` stays: most crops are transparent PNG->webp, so this is what
   shows behind a logo that doesn't fill its circle edge-to-edge, and it
   covers the instant before the image has loaded. */
.vh-college-logo {
  flex: none;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  overflow: hidden;
  border: 1px solid #dfe2ea;
  background: #f1f2f6;
  display: grid;
  place-items: center;
}
.vh-college-logo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.vh-college span {
  font-size: 0.94rem;
  font-weight: 600;
  text-align: left;
  line-height: 1.2;
  white-space: nowrap;
}
/* A marquee is motion for its own sake, so under reduced motion it stops
   completely — but it must not stay parked at -50% with its first half off
   screen, so the transform is reset and the row becomes scrollable instead. */
@media (prefers-reduced-motion: reduce) {
  .vh-marquee { overflow-x: auto; }
  .vh-marquee-track { transform: none; }
}

/* ---------- responsive ---------- */
@media (max-width: 1100px) {
  .vh-cbt { grid-template-columns: minmax(0, 1fr); gap: 34px; }
  .vh-voice-grid { grid-template-columns: minmax(0, 1fr); gap: 24px; }
  .vh-voice-photo { min-height: 190px; }
  img.vh-voice-photo { height: 190px; }
  /* Stacked layout: the text now spans the FULL width, so the light left end of
     the horizontal gradient would sit under it. Flat 0.86 everywhere instead —
     the same figure the text half uses on desktop. */
  .vh-voice::before {
    background-image:
      linear-gradient(rgba(0, 0, 0, 0.86), rgba(0, 0, 0, 0.86)),
      var(--vh-voice-photo, none);
  }
  /* The watermark stays absolute at every width — the clamp already takes it
     small enough on a phone to fit inside the section's bottom padding without
     touching the chips. Making it static instead put a full-bleed line hard
     against the right edge of the viewport. */
}

@media (max-width: 900px) {
  .vh-new-grid { grid-template-columns: minmax(0, 1fr); }
  .vh-join-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 720px) {
  .vh-tiers { grid-template-columns: minmax(0, 1fr); gap: 12px; }
  .vh-join-grid { grid-template-columns: minmax(0, 1fr); }
  .vh-bydm { grid-template-columns: minmax(0, 1fr); gap: 30px; text-align: center; }
  /* stacked: the art is centred under the copy, so the desktop right-push has
     to be released or it hugs the right edge on a phone */
  .vh-bydm-art img { margin-inline: auto; }
  .vh-form { padding: 20px 18px 24px; }
  .vh-new, .vh-join, .vh-colleges { padding-block: 46px; }
  .vh-voice { padding-block: 30px; }
  /* the brand label leaves the top-right corner and sits above the title, so a
     narrow card does not have to reserve width for it */
  .vh-pcard-brand { position: static; margin-bottom: 8px; }
}
