/* Platform global stylesheet.
 *
 * Text-shaping rules below force Blink/WebKit engines (Google Chrome, Edge
 * and mobile browsers) to shape conjuncts, cluster bases and ligatures for
 * complex Indic scripts such as Bengali. Without these declarations the GPU
 * text rasterizer can drop the matra/conjunct joining marks that Bangla text
 * relies on, so candidate names, question copy and PDF-derived labels can
 * appear broken or spuriously spaced.
 */
html,
body {
  /* Render OpenType contextual + common ligatures (juktakkhor joining). */
  font-variant-ligatures: common-ligatures contextual;
  /* Ask the shaping engine to prefer glyph-level legibility over raw speed. */
  text-rendering: optimizeLegibility;
  /* Sub-pixel vs. grayscale antialiasing switch for the WebKit/Blink stack. */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* Default family stack: Latin system faces first, then the regional fallbacks
   (Noto Sans Bengali / Hind Siliguri) that supply the conjunct glyphs used by
   Bangla UI text. The text-shaping properties above still apply to any
   element, including Tailwind utility output. */
body {
  font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
    "Helvetica Neue", Arial, "Noto Sans Bengali", "Hind Siliguri",
    "SolaimanLipi", sans-serif;
}

/* Elements explicitly carrying Bangla copy inherit the shaping settings and
   prefer the regional faces ahead of the generic fallback list. */
.lang-bn,
.bn-text,
[lang="bn"] {
  font-family: "Hind Siliguri", "Noto Sans Bengali", "SolaimanLipi",
    "Vrinda", ui-sans-serif, system-ui, sans-serif;
}

/* ---------------------------------------------------------------------------
   Responsive safety overrides
   Guarantee form controls, buttons, grids and tables never push the layout
   past the viewport on narrow screens. Action/filter toolbars are allowed to
   wrap so their buttons stay reachable instead of overflowing.
--------------------------------------------------------------------------- */

*,
*::before,
*::after {
  box-sizing: border-box;
}

input,
select,
textarea,
button {
  max-width: 100%;
  box-sizing: border-box;
}

img,
svg,
video,
canvas {
  max-width: 100%;
  height: auto;
}

/* Responsive action/filter toolbars: wrap onto further lines and keep their
   actions aligned to the end on small viewports. */
.responsive-panel,
.action-bar,
.filter-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  justify-content: flex-end;
}

/* Field cells inside a filter toolbar size evenly but never below the usable
   mobile width; the trailing action cell keeps its natural size so the
   Apply/Clear buttons hug the right edge of the last row. */
.filter-bar > div {
  flex: 1 1 180px;
  min-width: 150px;
}

.filter-bar > div:last-child {
  flex-grow: 0;
}

.table-container,
table {
  max-width: 100%;
}

@media (max-width: 640px) {
  .table-container,
  table {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
}

/* Explicit horizontal scroll containers for dense data tables (backup ledger,
   administrator matrix). The wrapper takes the full card width and scrolls its
   columns on the horizontal axis with native momentum scrolling so long rows or
   Note-style text blocks never bleed past the frame borders on smartphones. */
.table-scroll {
  display: block;
  width: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

/* Modal content cards: clip full-bleed inner header bands to the card's own
   rounded corners so coloured headers never poke square corners out of the
   rounded frame while an overlay is open. */
.modal-content {
  overflow: hidden;
}

/* Question media: a bounded figure rendered under the prompt wherever a
   question carries an uploaded diagram/visual aid. Never overflows its card,
   keeps aspect ratio and can be referenced safely inside flex containers. */
.question-diagram {
  max-width: 100%;
  height: auto;
  display: block;
  margin: 15px 0;
  object-fit: contain;
  border-radius: 8px;
}

/* ---------------------------------------------------------------------------
   Contextual profile-selector creation gates
   Creation actions (Create New Exam Batch, Add Question, Create Eligibility
   Roster, Send Broadcast) remain locked while the Active Exam Profile Selector
   sits on its default 'All Exams (no isolation)' state. The wrapper span holds
   the hover tooltip (data-gate-tip) while its contained control is disabled
   and visually de-emphasised so the unlock requirement reads at a glance.
--------------------------------------------------------------------------- */

.btn-profile-gate {
  position: relative;
  display: inline-block;
}

.btn-profile-gate.gate-locked {
  cursor: not-allowed;
}

.btn-profile-gate.gate-locked > button,
.btn-profile-gate.gate-locked > input[type="submit"] {
  opacity: 0.55;
  filter: grayscale(1);
  pointer-events: none;
  box-shadow: none !important;
}

/* Hover tooltip pinned above the disabled control; the pointer-events:none on
   the button lets the wrapper receive the hover so the hint always appears. */
.btn-profile-gate.gate-locked::after {
  content: attr(data-gate-tip);
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%);
  width: max-content;
  max-width: 260px;
  background: #0f172a;
  color: #f1f5f9;
  font-size: 0.72rem;
  line-height: 1.35;
  font-weight: 600;
  padding: 0.45rem 0.6rem;
  border-radius: 0.5rem;
  text-align: center;
  z-index: 300;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s ease;
  box-shadow: 0 6px 18px rgba(15, 23, 42, 0.25);
}

.btn-profile-gate.gate-locked:hover::after {
  opacity: 1;
}

/* ---------------------------------------------------------------------------
   Responsive field-block overrides for dense admin forms

   1) Exam Blueprint category-rule rows: the desktop builder paints each rule
      as a single flat six-column track grid. On phones that row cannot shrink
      (fixed 130px/90px tracks + input min-content), so every category rule is
      re-flowed here into a compact nested multi-row card so Category,
      Difficulty, Quota, Section/Part, the Manual toggle and the delete "x"
      stack inside the card frame instead of bleeding out of it.
   2) Roles & Permission Matrix role-key column: raw key tokens (super_admin,
      exam_admin, ...) render inside a bordered monospace capsule that never
      text-wraps; if the viewport narrows past the capsule's natural width the
      pill degrades to an inner horizontal scroll so it never clips the matrix
      panel boundary lines.
   3) Question Bank Import block + Registration Terms rows: trailing controls
      are anchored to the right-hand border with balanced wrapping flex
      containers so long inputs wrap internally instead of escaping the card.
--------------------------------------------------------------------------- */

/* ---- 1) Exam Blueprint rules: vertical 4-line category cards on mobile ----
   Desktop keeps the compact single-line table row (column captions render in
   .bp-rule-grid-head). Each rule row also carries mobile-only field captions
   (.bp-rule-lbl, display:none on wide screens). On phones the row is re-painted
   as its own vertical card:
     line 1  Category Name                                (full width)
     line 2  Difficulty                                   (full width)
     line 3  Question Quota Count | Section / Part        (50/50, top labels)
     line 4  Manual Review ..................... remove x  (bottom strip)  */
.bp-rule-lbl {
  display: none; /* captions are the desktop table-header cells instead */
}

.bp-rule-row > * {
  min-width: 0;
}

@media (max-width: 768px) {
  /* The static column caption strip is meaningless once each rule card stacks
     into rows, so hide it and let the per-card labels speak instead. */
  .bp-rule-grid-head {
    display: none !important;
  }

  .bp-rule-lbl {
    display: block;
    font-size: 0.62rem;
    line-height: 1.1;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: #64748b; /* slate-500 */
  }

  .dark .bp-rule-lbl {
    color: #94a3b8; /* slate-400 */
  }

  /* Distinct nested vertical card: two fluid columns; explicit placements
     rebuild the required four stacked lines below. */
  .bp-rule-row {
    display: grid !important;
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
    gap: 0.4rem 0.55rem !important;
    align-items: start !important;
    border: 1px solid rgba(100, 116, 139, 0.22);
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.06);
  }

  /* Line 1: Category Name caption + full-width input */
  .bp-rule-row > :nth-child(1) {
    grid-column: 1 / -1;
    grid-row: 1;
  }

  .bp-rule-row > :nth-child(2) {
    grid-column: 1 / -1;
    grid-row: 2;
  }

  /* Line 2: Difficulty caption + full-width selector */
  .bp-rule-row > :nth-child(3) {
    grid-column: 1 / -1;
    grid-row: 3;
  }

  .bp-rule-row > :nth-child(4) {
    grid-column: 1 / -1;
    grid-row: 4;
  }

  /* Line 3: Quota (left) + Section/Part (right) split 50/50 with labels
     stacked directly above each field. */
  .bp-rule-row > :nth-child(5) {
    grid-column: 1;
    grid-row: 5;
  }

  .bp-rule-row > :nth-child(7) {
    grid-column: 2;
    grid-row: 5;
  }

  .bp-rule-row > :nth-child(6) {
    grid-column: 1;
    grid-row: 6;
  }

  .bp-rule-row > :nth-child(8) {
    grid-column: 2;
    grid-row: 6;
  }

  /* Line 4: Manual Review toggle left, remove 'x' pinned to the far right */
  .bp-rule-row > :nth-child(9) {
    grid-column: 1;
    grid-row: 7;
    align-self: center;
  }

  .bp-rule-row > :nth-child(10) {
    grid-column: 2;
    grid-row: 7;
    justify-self: end;
    align-self: center;
  }

  .bp-rule-row input,
  .bp-rule-row select {
    width: 100%;
    box-sizing: border-box;
  }
}

/* ---- 2) Roles & Permission Matrix: multi-line role cards on mobile ----
   Wide screens keep the single horizontal strip (role name field + role-key
   capsule + BUILT-IN/CUSTOM tag + assigned count + Active switch + Save).
   Below 768px the card header stacks into distinct structural lines:
     line 1  Role Name rendered full width in bold
     line 2  Role Key token inside its developer pill capsule
     line 3  type tag | assigned-count block | Active switch in one strip   */
.role-key-pill,
.perm-key-pill {
  white-space: nowrap;
  max-width: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
}

/* Give the role-key capsule enough room next to the role-name field even when
   the matrix card is compressed; the capsule scrolls internally rather than
   shoving the whole header row past the panel boundary. */
.role-key-cell {
  min-width: 0;
}

@media (max-width: 768px) {
  .role-card-head {
    gap: 0.4rem 0.7rem;
    align-items: center;
  }

  /* Line 1 + Line 2: role cell owns the top of the card and re-flows itself */
  .role-card-head > .role-key-cell {
    flex: 1 1 100%;
    min-width: 0;
    flex-wrap: wrap;
    gap: 0.3rem 0.5rem;
  }

  /* The tiny "Role" column caption is redundant once the name owns the line. */
  .role-card-head > .role-key-cell > span {
    display: none;
  }

  .role-card-head > .role-key-cell > input[type="text"] {
    flex: 1 1 100%;
    min-width: 0;
    font-weight: 700;
    font-size: 0.95rem;
    line-height: 1.25;
  }

  /* Line 3: type tag, assigned-count block and Active switch flow as a single
     balanced horizontal strip; oversized rows wrap gracefully. */
  .role-card-head > *:not(.role-key-cell) {
    flex: 0 0 auto;
  }

  .role-card-head > button[type="submit"] {
    margin-left: auto;
  }
}

/* ---- 3) Question Bank Import + Registration Terms rows ---- */
.qb-import-wrap,
.qb-import-form {
  max-width: 100%;
  min-width: 0;
}

.qb-import-form input[type="file"] {
  min-width: 0;
  max-width: 100%;
}

@media (max-width: 640px) {
  .qb-import-wrap {
    width: 100%;
  }

  .qb-import-form > * {
    max-width: 100%;
  }

  /* Compact footprint so select + file + Import never spill off the phone. */
  .qb-import-form select,
  .qb-import-form button {
    padding: 0.3rem 0.45rem;
    font-size: 0.72rem;
    line-height: 1.25;
  }

  .qb-import-form input[type="file"] {
    max-width: 9.5rem;
    min-width: 0;
    font-size: 0.72rem;
    white-space: nowrap;
    text-overflow: ellipsis;
    overflow: hidden;
  }
}

/* Term rows: flex-balanced on every breakpoint so the term text field flexes
   while the remove "x" stays anchored against the right-hand frame border. */
.term-row {
  display: flex !important;
  align-items: center;
  gap: 0.5rem 0.6rem;
}

.term-row > input[type="text"] {
  flex: 1 1 auto;
  min-width: 0;
}

.term-row > label {
  flex: 0 0 130px;
  min-width: 0;
}

.term-row > button:last-child {
  flex: 0 0 auto;
}

@media (max-width: 768px) {
  .rt-term-head {
    display: none !important;
  }

  /* Every term row becomes a balanced, wrapping flex block: the term input
     claims its own full line while the Mandatory toggle and remove "x" sit on
     the following line with the "x" pinned to the right-hand card border. */
  .term-row {
    flex-wrap: wrap;
    justify-content: space-between;
    gap: 0.4rem 0.5rem;
    word-break: break-word;
  }

  .term-row > input[type="text"] {
    flex: 1 1 100%;
  }

  .term-row > label {
    flex: 0 1 auto;
    margin-right: auto;
  }
}

/* ==========================================================================
   Exam Profile Selector embedded in the global gradient navbar
   The selector chip ships self-contained inside _exam_profile_selector.html.
   When that partial is rendered inside a top <nav> it must shed its standalone
   white "card" look (sticky, card background, label color) and sit flush as a
   plain inline control between the brand cluster and the account cluster.
   ========================================================================== */
nav .profile-selector {
  position: static;
  margin: 0;
  padding: 0;
  border: 0;
  justify-content: flex-start;
}
nav .profile-selector-label {
  color: #fff;
  text-shadow: 0 1px 2px rgba(15, 23, 42, 0.45);
}
nav .profile-selector-pip {
  box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.25);
}
nav .profile-selector-select {
  min-width: 230px;
  color: #0f172a;
  background-color: #f8fafc;
  border-color: rgba(255, 255, 255, 0.55);
}


/* -------------------------------------------------------------------------
 * Phase 5 layout overhaul: left-aligned vertical sidebar application shell.
 * Every surface wraps its chrome in .app-shell so the locked 64-width
 * sidebar column (w-64) and the flex-1 content column share one viewport.
 * ---------------------------------------------------------------------- */
.app-shell {
  display: flex;
  align-items: stretch;
  min-height: 100vh;
  width: 100%;
}
.app-shell-main {
  flex: 1 1 0%;
  min-width: 0;
  display: flex;
  flex-direction: column;
}
@media (min-width: 768px) {
  /* Desktop: pin the 64-width sidebar as a fixed left column so the content
     viewport's md:pl-64 offset becomes the single 64-unit gutter (no double
     spacing against the flex shell). */
  #appSidebar {
    position: fixed;
    top: 0;
    left: 0;
    height: 100vh;
    z-index: 40;
  }
}
@media (max-width: 767px) {
  /* Small screens: the vertical panel collapses so content owns the viewport. */
  #appSidebar { display: none; }
}
