a{
  text-decoration: none;
}

th{
  font-weight: bold;
}

/* ==================================================================
   MOBILE / RESPONSIVE  — this app is used primarily on phones
   ================================================================== */

/* Long unbroken strings (URLs, IDs) must wrap, never widen the page */
@media (max-width: 767.98px){
  .content-wrapper .card, .content-wrapper p, .content-wrapper td, .content-wrapper li{
    overflow-wrap: break-word;
  }
}

/* ==================================================================
   LOGIN SCREEN — layout driven by site.login_image_position:
   left · right · top · bottom · cover · none   (body.login-pos-*)
   The photo's crop focus comes from site.login_image_focus, applied
   inline as background-position on .login-photo.
   ================================================================== */
.login-viewport{ min-height: 100vh; min-height: 100dvh; }

.login-shell{ display: flex; width: 100%; align-items: stretch; }
.login-shell .login-photo{
  flex: 1 1 0%;
  background-size: cover;
  background-position: center;      /* overridden inline by login_image_focus */
  background-repeat: no-repeat;
  min-height: 180px;
}
.login-shell .login-form-col{
  flex: 1 1 0%;
  display: flex; align-items: center; justify-content: center;
}
.brand-login-panel{ width: 100%; max-width: 26rem; padding: 3rem 2.5rem; }

/* --- Side by side (left / right): photo + a fixed-width form rail --- */
@media (min-width: 768px){
  .login-pos-left  .login-shell{ flex-direction: row; }
  .login-pos-right .login-shell{ flex-direction: row-reverse; }
  .login-pos-left  .login-form-col,
  .login-pos-right .login-form-col{ flex: 0 0 30rem; }
  .login-pos-left  .brand-login-panel,
  .login-pos-right .brand-login-panel{ max-width: 24rem; }
}

/* --- Stacked (top / bottom): a photo band above / below the form --- */
.login-pos-top    .login-shell{ flex-direction: column; }
.login-pos-bottom .login-shell{ flex-direction: column-reverse; }
.login-pos-top    .login-photo,
.login-pos-bottom .login-photo{ flex: 0 0 38vh; }

/* --- Cover: photo fills the screen, form floats as a card on top --- */
.login-pos-cover .login-shell{ position: relative; min-height: 100vh; min-height: 100dvh; }
.login-pos-cover .login-photo{ position: absolute; inset: 0; }
.login-pos-cover .login-shell::after{
  content: ""; position: absolute; inset: 0; background: rgba(0, 0, 0, .4);
}
.login-pos-cover .login-form-col{ position: relative; z-index: 1; margin: auto; padding: 1.5rem; }
.login-pos-cover .brand-login-panel{
  max-width: 25rem; border-radius: 1rem;
  background: var(--bs-body-bg, #fff);
  box-shadow: 0 1.5rem 3.5rem rgba(0, 0, 0, .35);
}

/* --- None: no photo, a single centred form --- */
.login-pos-none .login-photo{ display: none; }

/* --- Phones: the side layouts drop the photo and just show the form --- */
@media (max-width: 767.98px){
  .login-pos-left  .login-shell,
  .login-pos-right .login-shell{ flex-direction: column; }
  .login-pos-left  .login-photo,
  .login-pos-right .login-photo{ display: none; }
  .login-pos-top .login-photo,
  .login-pos-bottom .login-photo{ flex-basis: 32vh; }
  body.brand-login-page .brand-login-panel{
    padding-left: 1.5rem !important; padding-right: 1.5rem !important;
    padding-top: 2.5rem; padding-bottom: 2.5rem;
  }
}

/* ------------------------------------------------------------------
   Responsive data tables → stacked cards on phones
   Add class "rt-cards" to the .table-responsive wrapper and
   data-label="Column name" to each <td>/<th> in the body rows.
   The action-buttons cell gets class "rt-actions" instead of a label.
   ------------------------------------------------------------------ */
@media (max-width: 767.98px){
  .rt-cards{ overflow-x: visible; }
  .rt-cards > table,
  .rt-cards > table > tbody{ display: block; width: 100%; }
  .rt-cards > table > thead{
    position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip: rect(0 0 0 0); white-space: nowrap;
  }
  .rt-cards > table > tbody > tr{
    display: block;
    border: 1px solid var(--bs-border-color, #e4e6e8);
    border-radius: .5rem;
    padding: .35rem .6rem;
    margin-bottom: .6rem;
    background: var(--bs-card-bg, #fff);
  }
  .rt-cards > table > tbody > tr > td,
  .rt-cards > table > tbody > tr > th{
    display: flex; align-items: center; gap: .35rem;
    padding: .45rem 0 !important;
    border: 0 !important;
    white-space: normal !important;
    text-align: right;
    font-weight: 400;
    min-height: 0;
    overflow-wrap: anywhere;
  }
  .rt-cards > table > tbody > tr > td + td,
  .rt-cards > table > tbody > tr > th + td,
  .rt-cards > table > tbody > tr > td + th{
    border-top: 1px solid var(--bs-border-color, #f0f0f2) !important;
  }
  .rt-cards > table > tbody > tr > td[data-label]::before,
  .rt-cards > table > tbody > tr > th[data-label]::before{
    content: attr(data-label);
    font-weight: 600; text-transform: uppercase;
    font-size: .68rem; letter-spacing: .03em;
    color: var(--bs-secondary-color, #8a8d93);
    text-align: left; margin-right: auto;
    flex: 0 0 auto; max-width: 45%;
    white-space: nowrap;
    align-self: center;
  }
  /* value side may wrap / shrink under a long label */
  .rt-cards > table > tbody > tr > td > *,
  .rt-cards > table > tbody > tr > th > *{ min-width: 0; }
  .rt-cards > table > tbody > tr > td > .form-control,
  .rt-cards > table > tbody > tr > td > .form-select,
  .rt-cards > table > tbody > tr > td > input,
  .rt-cards > table > tbody > tr > td > select{ flex: 0 1 60%; width: auto; }
  /* rows with no data-label (colspan empty-states, etc.) stay centered */
  .rt-cards > table > tbody > tr > td:not([data-label]):only-child{ justify-content: center; text-align: center; }

  /* long-text cells: stack the label above a full-width value */
  .rt-cards > table > tbody > tr > td.rt-block{
    flex-direction: column; align-items: stretch; text-align: left; gap: .15rem;
  }
  .rt-cards > table > tbody > tr > td.rt-block[data-label]::before{
    margin-right: 0; max-width: none;
  }
  .rt-cards > table > tbody > tr > td.rt-block > .form-control,
  .rt-cards > table > tbody > tr > td.rt-block > .form-select{ flex: 1 1 auto; }

  /* action buttons: full-width strip, no label, first in the card */
  .rt-cards > table > tbody > tr > .rt-actions{
    order: -1;
    flex-wrap: wrap; justify-content: flex-start; gap: .4rem;
    padding: .15rem 0 .5rem !important;
    border: 0 !important;
    border-bottom: 1px solid var(--bs-border-color, #f0f0f2) !important;
    margin-bottom: .15rem;
  }
  .rt-cards > table > tbody > tr > .rt-actions::before{ display: none; }
  .rt-cards > table > tbody > tr > .rt-actions .btn{ margin: 0; }

  /* the running serial "#" cell — keep it quiet */
  .rt-cards > table > tbody > tr > td.rt-sn,
  .rt-cards > table > tbody > tr > th.rt-sn{ display: none; }
}

/* ------------------------------------------------------------------
   Filter / search bars — stack controls on phones
   Add class "filters-wrap" to the flex/input-group container.
   ------------------------------------------------------------------ */
@media (max-width: 767.98px){
  .filters-wrap{ display: flex; flex-wrap: wrap; gap: .5rem; }
  .filters-wrap > .form-control,
  .filters-wrap > .form-select,
  .filters-wrap > input,
  .filters-wrap > select{
    width: 100% !important; flex: 1 1 100%; min-width: 0;
    border-radius: var(--bs-border-radius, .375rem) !important;
  }
  .filters-wrap > .btn{ flex: 1 1 calc(50% - .25rem); width: auto !important; min-width: 0; }
}

/* ------------------------------------------------------------------
   Charts (ApexCharts). A swipe that starts on a chart must still
   scroll the page — the browser keeps vertical panning. Toolbar
   (chart-nav.js): ‹ › slide, + − zoom, ⌂ reset.
   ------------------------------------------------------------------ */
.apexcharts-canvas{
  touch-action: pan-y;
}

.apexcharts-toolbar{ gap: 3px; align-items: center; }
.apexcharts-toolbar .cn-btn{
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; cursor: pointer;
  color: var(--bs-secondary-color, #6e8192);
  transition: color .12s ease, border-color .12s ease, background-color .12s ease;
}
.apexcharts-toolbar .cn-btn:hover{ color: var(--bs-heading-color, #384551); }
/* the two slide buttons get a circular border */
.apexcharts-toolbar .cn-slide{
  width: 24px; height: 24px; margin: 0 1px;
  border: 1.5px solid var(--bs-border-color, #c7ccd6);
  border-radius: 50%;
}
.apexcharts-toolbar .cn-slide:hover{
  border-color: currentColor;
  background-color: rgba(105, 108, 255, .08);
}
.apexcharts-toolbar .cn-btn svg{ display: block; }

/* ------------------------------------------------------------------
   FullCalendar — stack the toolbar so it never overflows
   ------------------------------------------------------------------ */
@media (max-width: 767.98px){
  #calendar .fc-toolbar.fc-header-toolbar{
    display: flex; flex-direction: column; align-items: stretch; gap: .5rem;
    margin-bottom: 1rem;
  }
  #calendar .fc-toolbar-chunk{ display: flex; justify-content: center; }
  #calendar .fc-toolbar-title{ font-size: 1.05rem; text-align: center; }
  #calendar .fc .fc-button{ padding: .35rem .55rem; font-size: .8rem; }
  #calendar .fc .fc-toolbar-chunk > .fc-button-group,
  #calendar .fc .fc-toolbar-chunk > .fc-button{ flex: 1 1 auto; }
  #calendar .fc-daygrid-day-number{ font-size: .8rem; }
  #calendar .fc-col-header-cell-cushion{ font-size: .72rem; }
  #calendar .fc-view-harness{ min-height: 420px; }
}

/* ------------------------------------------------------------------
   Page title / back-button header row on small screens
   ------------------------------------------------------------------ */
@media (max-width: 575.98px){
  .content-wrapper .row.m-0.py-3 > div{ width: 100%; }
  .content-wrapper .row.m-0.py-3 .btn{ margin-top: .25rem; }
}

/* Tap targets: give small icon buttons a comfortable size on touch */
@media (max-width: 767.98px){
  .btn-icon.btn-sm{ width: 2.25rem; height: 2.25rem; }
  .quick-actions{ grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); }
  .metric-strip{ grid-template-columns: repeat(auto-fit, minmax(90px, 1fr)); }
  .table-responsive .btn-sm{ white-space: nowrap; }
}

/* ------------------------------------------------------------------
   Professional polish – shared building blocks
   ------------------------------------------------------------------ */

/* Page header (title + subtitle + actions) */
.page-header{
  display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between;
  gap:.75rem; margin-bottom:1.25rem;
}
.page-header .page-title{ margin:0; font-weight:700; line-height:1.2; }
.page-header .page-subtitle{ margin:.15rem 0 0; color:var(--bs-secondary-color,#8a8d93); font-size:.875rem; }

/* Filter bar */
.filter-bar{ margin-bottom:1.25rem; }
.filter-bar .card-body{ padding:1rem 1.25rem; }
.filter-bar label{ font-size:.75rem; text-transform:uppercase; letter-spacing:.04em; font-weight:600;
  color:var(--bs-secondary-color,#8a8d93); margin-bottom:.25rem; }
.filter-bar .form-control, .filter-bar .form-select{ background-color:#fff; }

/* Stat / KPI card */
.stat-card{ border:0; height:100%; transition:transform .15s ease, box-shadow .15s ease; }
.stat-card:hover{ transform:translateY(-3px); box-shadow:0 .5rem 1.25rem rgba(0,0,0,.08); }
.stat-card .stat-icon{
  width:2.75rem; height:2.75rem; border-radius:.65rem; display:flex; align-items:center;
  justify-content:center; font-size:1.15rem; flex:none;
}
.stat-card .stat-value{ font-size:1.6rem; font-weight:700; line-height:1.1; }
.stat-card .stat-label{ color:var(--bs-secondary-color,#8a8d93); font-size:.8rem; text-transform:uppercase;
  letter-spacing:.03em; }

/* Definition grid (profiles) */
.info-grid{ display:grid; grid-template-columns:repeat(auto-fit,minmax(220px,1fr)); gap:.85rem 1.5rem; }
.info-grid .info-item{ min-width:0; }
.info-grid .info-label{ font-size:.72rem; text-transform:uppercase; letter-spacing:.04em; font-weight:600;
  color:var(--bs-secondary-color,#8a8d93); }
.info-grid .info-value{ font-weight:600; word-break:break-word; }

/* Profile header */
.profile-header{ display:flex; flex-wrap:wrap; gap:1.25rem; align-items:center; }
.profile-header .profile-avatar{ width:104px; height:104px; border-radius:1rem; object-fit:cover;
  border:3px solid rgba(255,255,255,.6); background:#eee; flex:none; }
.profile-header .profile-name{ font-weight:700; margin:0; }

/* Current-picture preview on an update form (student/teacher/user) */
.picture-preview{ width:64px; height:64px; border-radius:.5rem; object-fit:cover;
  object-position:top; border:1px solid var(--bs-border-color,#e4e6e8); background:#eee; flex:none; }

/* Empty state */
.empty-state{ text-align:center; padding:3rem 1rem; color:var(--bs-secondary-color,#8a8d93); }
.empty-state .empty-icon{ font-size:2.5rem; opacity:.35; margin-bottom:.75rem; }
.empty-state h5{ color:var(--bs-heading-color,#566a7f); font-weight:600; }

/* Tables: sticky header + tidy */
.table-card .table{ margin-bottom:0; }
.table-card .table thead th{ position:sticky; top:0; z-index:1; }
.table-hover-rows tbody tr{ transition:background-color .12s ease; }

/* Calendar tweaks */
#calendar .fc .fc-toolbar-title{ font-size:1.15rem; font-weight:700; }
#calendar .fc-daygrid-event{ white-space:normal; border-radius:.35rem; padding:1px .35rem; font-weight:600; font-size:.75rem; }
#calendar .fc-day-today{ background:rgba(var(--bs-primary-rgb,105,108,255),.08) !important; }
#calendar .fc-col-header-cell-cushion{ font-weight:700; }
#calendar .fc .fc-button{ text-transform:capitalize; }
#calendar .fc-daygrid-day-number{ font-weight:600; }

.cal-legend{ display:flex; flex-wrap:wrap; gap:.25rem 1rem; margin-bottom:.6rem; font-size:.8rem; color:var(--bs-secondary-color,#8a8d93); }
.cal-legend span{ display:inline-flex; align-items:center; }
.cal-dot{ width:.7rem; height:.7rem; border-radius:50%; margin-right:.35rem; display:inline-block; }

/* Insights panel (auto analysis) */
.insight-section + .insight-section{ margin-top:1rem; }
.insight-section-title{
  font-size:.72rem; font-weight:700; text-transform:uppercase; letter-spacing:.05em;
  color:var(--bs-secondary-color,#8a8d93); margin-bottom:.4rem;
}
.insight-list{ list-style:none; margin:0; padding:0; display:grid; gap:.4rem; }
.insight{
  display:flex; align-items:flex-start; gap:.6rem; padding:.5rem .75rem; border-radius:.4rem;
  border-left:3px solid var(--bs-border-color,#eceef1);
  background:rgba(var(--bs-secondary-rgb,133,146,163),.06); font-size:.88rem; line-height:1.35;
}
.insight i{ margin-top:.12rem; width:1rem; text-align:center; flex:none; }
.insight-good{ border-left-color:var(--bs-success,#71dd37); }
.insight-good i{ color:var(--bs-success,#71dd37); }
.insight-warn{ border-left-color:var(--bs-warning,#ffab00); }
.insight-warn i{ color:var(--bs-warning,#ffab00); }
.insight-bad{ border-left-color:var(--bs-danger,#ff3e1d); }
.insight-bad i{ color:var(--bs-danger,#ff3e1d); }
.insight-info{ border-left-color:var(--bs-info,#03c3ec); }
.insight-info i{ color:var(--bs-info,#03c3ec); }

/* ------------------------------------------------------------------
   Clickable everything
   ------------------------------------------------------------------ */
a.card, a.stat-card{ color:inherit; }
a.card:hover{ color:inherit; }
.card-clickable{ cursor:pointer; transition:transform .15s ease, box-shadow .15s ease; }
.card-clickable:hover{ transform:translateY(-3px); box-shadow:0 .5rem 1.25rem rgba(0,0,0,.1); }

/* clickable table rows */
tr.row-link{ cursor:pointer; }
tr.row-link:hover > *{ background-color:rgba(var(--bs-primary-rgb,105,108,255),.06); }

/* card header that is a link */
.card-header-link{ display:flex; align-items:center; justify-content:space-between; color:inherit; }
.card-header-link:hover{ color:inherit; }
.card-header-link .go{ opacity:.4; transition:opacity .15s, transform .15s; }
.card-header-link:hover .go{ opacity:1; transform:translateX(3px); }

/* Quick actions */
.quick-actions{ display:grid; grid-template-columns:repeat(auto-fill,minmax(160px,1fr)); gap:.75rem; }
.quick-actions .qa{
  display:flex; flex-direction:column; align-items:center; justify-content:center; text-align:center;
  gap:.4rem; padding:1rem .5rem; border:1px solid var(--bs-border-color,#eceef1); border-radius:.6rem;
  color:var(--bs-heading-color,#566a7f); background:var(--bs-card-bg,#fff);
  transition:transform .12s ease, box-shadow .12s ease, border-color .12s ease;
}
.quick-actions .qa:hover{ transform:translateY(-3px); box-shadow:0 .4rem 1rem rgba(0,0,0,.08);
  border-color:rgba(var(--bs-primary-rgb,105,108,255),.5); color:var(--bs-primary,#696cff); }
.quick-actions .qa i{ font-size:1.35rem; }
.quick-actions .qa span{ font-size:.82rem; font-weight:600; }

/* ------------------------------------------------------------------
   Profile alignment fixes
   ------------------------------------------------------------------ */
.profile-header{ align-items:center; }
.profile-header .profile-avatar{ cursor:zoom-in; }
.profile-header .ph-main{ flex:1 1 auto; min-width:0; }
.profile-header .ph-actions{ display:flex; flex-direction:column; gap:.5rem; flex:none; }
.profile-header .profile-name{ font-size:1.35rem; }
.profile-header .badge{ font-weight:600; }
@media (max-width:575.98px){
  .profile-header{ flex-direction:column; text-align:center; gap:.85rem; }
  .profile-header .ph-actions{ flex-direction:row; justify-content:center; flex-wrap:wrap; }
}

/* Position / result summary strip */
.metric-strip{ display:grid; grid-template-columns:repeat(auto-fit,minmax(120px,1fr)); gap:.5rem; }
.metric-strip .metric{ text-align:center; padding:.85rem .5rem; border-radius:.5rem;
  background:rgba(var(--bs-primary-rgb,105,108,255),.05); }
.metric-strip .metric .m-label{ font-size:.7rem; text-transform:uppercase; letter-spacing:.04em;
  font-weight:600; color:var(--bs-secondary-color,#8a8d93); display:block; margin-bottom:.25rem; }
.metric-strip .metric .m-value{ font-size:1.35rem; font-weight:700; line-height:1.1; }

/* Result table clarity */
.result-table td, .result-table th{ vertical-align:middle; }
.progress.pct-bar{ height:.5rem; min-width:80px; flex:1 1 auto; }

/* Latest-result spotlight (student profile) — plain, clean card at all
   times (just the top accent border identifies it). No permanent effect. */
.latest-result-card{
  border:0; border-top:3px solid var(--bs-primary,#696cff);
}

/* Published under 24h ago — a 3s vibrate the moment the page loads, then
   once that's done a softly pulsing glow around the border for as long as
   it stays "fresh" (i.e. only within that 24h window, never longer). */
.latest-result-fresh{
  animation: latest-result-shake 3s ease-in-out,
             latest-result-border-glow 2s ease-in-out 3s infinite;
}
@keyframes latest-result-shake{
  0%, 100%{ transform:translateX(0); }
  4%{ transform:translateX(-5px); }
  8%{ transform:translateX(5px); }
  12%{ transform:translateX(-5px); }
  16%{ transform:translateX(5px); }
  20%{ transform:translateX(-5px); }
  24%{ transform:translateX(5px); }
  28%{ transform:translateX(-5px); }
  32%{ transform:translateX(5px); }
  36%{ transform:translateX(-4px); }
  40%{ transform:translateX(4px); }
  44%{ transform:translateX(-4px); }
  48%{ transform:translateX(4px); }
  52%{ transform:translateX(-3px); }
  56%{ transform:translateX(3px); }
  60%{ transform:translateX(-3px); }
  64%{ transform:translateX(3px); }
  68%{ transform:translateX(-2px); }
  72%{ transform:translateX(2px); }
  76%{ transform:translateX(-2px); }
  80%{ transform:translateX(2px); }
  84%{ transform:translateX(-1px); }
  88%{ transform:translateX(1px); }
  92%{ transform:translateX(-1px); }
  96%{ transform:translateX(1px); }
}
@keyframes latest-result-border-glow{
  0%, 100%{ box-shadow:0 0 0 0 rgba(var(--bs-primary-rgb,105,108,255),.45); }
  50%{ box-shadow:0 0 18px 3px rgba(var(--bs-primary-rgb,105,108,255),.55); }
}
@media (prefers-reduced-motion: reduce){
  .latest-result-fresh{ animation:none; }
}

/* A row for an exam entered under 24h ago. No motion — just a quiet "focus"
   frame (primary-coloured border + faint tint) so a new entry stands out,
   paired with a "New" tag in the markup. Used on the exam list
   (read_exam_result) and on the matching row of the student-profile results
   table. Works on the desktop table (frame the <td>s with box-shadow, which
   ignores border-collapse) and the phone "rt-cards" view (frame the block <tr>). */
tr.exam-row-fresh > td{
  background-color: rgba(var(--bs-primary-rgb, 105, 108, 255), .06);
  box-shadow: inset 0  2px 0 0 var(--bs-primary, #696cff),
              inset 0 -2px 0 0 var(--bs-primary, #696cff);
}
tr.exam-row-fresh > td:first-child{
  box-shadow: inset 0  2px 0 0 var(--bs-primary, #696cff),
              inset 0 -2px 0 0 var(--bs-primary, #696cff),
              inset 2px 0 0 0 var(--bs-primary, #696cff);
}
tr.exam-row-fresh > td:last-child{
  box-shadow: inset 0  2px 0 0 var(--bs-primary, #696cff),
              inset 0 -2px 0 0 var(--bs-primary, #696cff),
              inset -2px 0 0 0 var(--bs-primary, #696cff);
}
@media (max-width: 767.98px){
  tr.exam-row-fresh{
    border-color: var(--bs-primary, #696cff) !important;
    box-shadow: 0 0 0 1px var(--bs-primary, #696cff);
    background-color: rgba(var(--bs-primary-rgb, 105, 108, 255), .06);
  }
  tr.exam-row-fresh > td,
  tr.exam-row-fresh > td:first-child,
  tr.exam-row-fresh > td:last-child{ box-shadow: none; }
}

/* ------------------------------------------------------------------
   Notice board (/board) — small static picture cards, no animation
   ------------------------------------------------------------------ */
.board-wrap{ max-width:1600px; margin:0 auto; }
.board-header{ position:relative; }
.board-tools{ position:fixed; right:.6rem; bottom:.6rem; z-index:1030; display:flex; gap:.35rem; }
.board-filter{ display:flex; flex-wrap:wrap; gap:.5rem; justify-content:center; margin-bottom:.75rem; }
.board-filter .form-select, .board-filter .form-control{ width:auto; min-width:9rem; }
.board-section-title{
  margin:.8rem 0 .4rem; font-weight:700; font-size:.95rem;
  border-bottom:1px solid var(--bs-border-color,#eceef1); padding-bottom:.25rem;
}
.board-grid{
  display:grid; gap:.4rem;
  grid-template-columns:repeat(auto-fill, minmax(var(--board-card,150px), 1fr));
}
.board-card{
  position:relative; display:block; text-align:center; padding:0;
  color:inherit; text-decoration:none;
  border-radius:.4rem; background:var(--bs-card-bg,#fff);
  border:1px solid var(--bs-border-color,#eceef1);
}
.board-card:hover{ color:inherit; border-color:var(--bs-primary,#696cff); }
.board-card .board-pic{
  overflow:hidden; width:100%; aspect-ratio:1/1;
  background:#e9e9ee; display:block; border-radius:.35rem .35rem 0 0;
}
.board-card .board-pic img{ width:100%; height:100%; object-fit:cover; display:block; }
.board-card .board-body{ padding:.2rem .3rem .3rem; }
.board-card .board-name{ font-weight:700; line-height:1.1; word-break:break-word; font-size:.78rem; }
.board-card .board-meta{ font-size:.68rem; color:var(--bs-secondary-color,#8a8d93); line-height:1.2; }
.board-card .rank-badge{
  position:absolute; top:.25rem; left:.25rem; z-index:3;
  min-width:1.35rem; height:1.35rem; padding:0 .3rem; border-radius:1rem;
  display:inline-flex; align-items:center; justify-content:center; gap:.15rem;
  font-weight:800; font-size:.72rem; color:#fff; white-space:nowrap;
}

/* ------------------------------------------------------------------
   Navbar user avatar — a fixed 40x40 circle, cropped from the top of
   the photo (not stretched into an oval by a height:auto image box).
   ------------------------------------------------------------------ */
.nav-avatar-img{ object-position: top; }

/* top-3: static colour ring + badge, nothing else */
.board-card.rank-1{ border-color:#f5c518; box-shadow:0 0 0 2px #f5c518; }
.board-card.rank-2{ border-color:#aeb6bd; box-shadow:0 0 0 2px #aeb6bd; }
.board-card.rank-3{ border-color:#cd7f32; box-shadow:0 0 0 2px #cd7f32; }
.board-card.rank-1 .rank-badge{ background:#f5c518; color:#3a2f00; }
.board-card.rank-2 .rank-badge{ background:#98a1a9; }
.board-card.rank-3 .rank-badge{ background:#cd7f32; }

/* ---------------------------------------------------------------
   Every cropped (object-fit:cover) picture is anchored to the TOP,
   so heads/faces are never cut off in portrait photos.
---------------------------------------------------------------- */
.object-fit-cover,
.profile-header .profile-avatar,
.profile-avatar,
.picture-preview,
.board-card .board-pic img,
.card-img-left,
.card-img-right,
.avatar img{ object-position: top !important; }
