/* ---------------------------------------------------------------------------
   app.css — layered on top of carbon.css (ported verbatim from the client
   prototype). This file holds only what the prototype could not: real embedded
   fonts, the three-language font stacks, and the accessibility corrections
   recorded in docs/design/03-ui-spec.md §4.

   Fonts are served from the binary at /fonts/*. No Google Fonts link: it fails
   on an air-gapped state IT network and adds a third-party privacy dependency
   (CLAUDE.md §15.3).
--------------------------------------------------------------------------- */

/* Montserrat stands in for Gotham, which the Figma is set in.
   Gotham is a licensed Hoefler&Co face and cannot be embedded in a binary we
   ship, and CLAUDE.md §2 requires everything to travel inside the binary.
   Montserrat is SIL OFL 1.1, geometric, and close enough in proportion that
   the design reads as intended. The licence ships beside it at
   /fonts/Montserrat-OFL.txt, as the OFL requires. */
@font-face {
  font-family: 'Montserrat';
  src: url('/fonts/Montserrat-Light.ttf') format('truetype');
  font-weight: 300; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Montserrat';
  src: url('/fonts/Montserrat-Regular.ttf') format('truetype');
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Montserrat';
  src: url('/fonts/Montserrat-Medium.ttf') format('truetype');
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Montserrat';
  src: url('/fonts/Montserrat-Bold.ttf') format('truetype');
  font-weight: 700; font-style: normal; font-display: swap;
}

@font-face {
  font-family: 'Noto Sans Gujarati';
  src: url('/fonts/NotoSansGujarati-Regular.ttf') format('truetype');
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Noto Sans Gujarati';
  src: url('/fonts/NotoSansGujarati-Bold.ttf') format('truetype');
  font-weight: 600; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Noto Sans Devanagari';
  src: url('/fonts/NotoSansDevanagari-Regular.ttf') format('truetype');
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Noto Sans Devanagari';
  src: url('/fonts/NotoSansDevanagari-Bold.ttf') format('truetype');
  font-weight: 600; font-style: normal; font-display: swap;
}

/* The font stack follows <html lang>, so a Gujarati page shapes correctly
   without a single per-element override. Latin glyphs still come from Plex
   because the Noto face is listed first only for the script it owns. */
html[lang='gu'] body,
html[lang='gu'] button,
html[lang='gu'] input,
html[lang='gu'] select,
html[lang='gu'] textarea {
  font-family: 'Noto Sans Gujarati', 'Montserrat', -apple-system, BlinkMacSystemFont, sans-serif;
}
html[lang='hi'] body,
html[lang='hi'] button,
html[lang='hi'] input,
html[lang='hi'] select,
html[lang='hi'] textarea {
  font-family: 'Noto Sans Devanagari', 'Montserrat', -apple-system, BlinkMacSystemFont, sans-serif;
}

/* Gujarati and Devanagari have taller ascenders and descenders than Latin;
   at the prototype's 1.5 line-height they collide. */
html[lang='gu'] body, html[lang='hi'] body { line-height: 1.65; }
html[lang='gu'] th,   html[lang='hi'] th   { white-space: normal; }

/* ---------------------------------------------------------------------------
   Accessibility corrections (G8 exit criterion: Lighthouse ≥ 90).
--------------------------------------------------------------------------- */

/* The prototype uses --g50 (#8d8d8d) for 11px secondary text. That is 2.9:1 on
   white — it fails WCAG AA. --g70 (#525252) is 7.4:1 and visually near
   identical at this size. */
.kpi-f, .chart-s, .tile-s, .bar-t small, .foot-m { color: var(--g70); }

/* Every interactive element gets a visible focus ring. The prototype only
   styled .tile:focus-visible. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--blue60);
  outline-offset: 2px;
}
.hdr a:focus-visible, .hdr button:focus-visible { outline-color: var(--blue40); }

/* Skip link — first tab stop on every page. */
.skip {
  position: absolute; left: -9999px; top: 0; z-index: 300;
  background: var(--blue60); color: #fff; padding: 11px 18px;
  font-size: 13px; font-weight: 600;
}
.skip:focus { left: 0; }

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

/* Wide content scrolls inside its own container; the page body never scrolls
   horizontally. */
.tblwrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

/* ---------------------------------------------------------------------------
   Language switcher — persistent in the header, three taps to any language
   from any page (CLAUDE.md §15.3).
--------------------------------------------------------------------------- */
.lang { display: inline-flex; align-items: stretch; margin-right: 4px; }
.lang form { display: inline-flex; }
.lang button {
  font-size: 11.5px; font-weight: 600; color: var(--g30);
  padding: 6px 10px; border-left: 1px solid var(--g80);
  background: transparent; transition: background .14s, color .14s;
}
.lang button:first-child { border-left: none; }
.lang button:hover { background: var(--g90); color: #fff; }
.lang button[aria-current='true'] { background: var(--blue60); color: #fff; }

/* ---------------------------------------------------------------------------
   Admin console. Desktop-only (CLAUDE.md §15.2) — below 672px it says so
   rather than rendering a broken grid.
--------------------------------------------------------------------------- */
.adm-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 12px; }
.adm-only { display: none; }
@media (max-width: 671px) {
  .adm-body { display: none; }
  .adm-only { display: block; }
}

/* Assign role: a module rail beside a four-column checkbox grid. */
.perm-wrap { display: grid; grid-template-columns: 216px 1fr; gap: 1px; background: var(--g20); border: 1px solid var(--g20); margin-top: 4px; }
.perm-rail { background: #fff; padding: 8px 0; }
.perm-r { display: flex; justify-content: space-between; align-items: center; gap: 8px;
  padding: 9px 14px 9px 12px; font-size: 13px; color: var(--g100); text-decoration: none;
  border-left: 3px solid transparent; }
.perm-r:hover { background: var(--g10); }
.perm-r.on { background: var(--g10); border-left-color: var(--saffron); font-weight: 600; }
.perm-n { font-size: 11.5px; color: var(--g70); font-variant-numeric: tabular-nums; }
.perm-pane { background: #fff; padding: 16px 18px 18px; }
.perm-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 4px 18px; }
.perm-c { display: flex; gap: 9px; align-items: flex-start; font-size: 12.5px; padding: 6px 0; cursor: pointer; }
.perm-d { color: var(--g70); font-size: 11.5px; }
.perm-act { display: flex; align-items: center; justify-content: space-between; gap: 16px;
  margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--g20); flex-wrap: wrap; }
.perm-hint { font-size: 12px; color: var(--g70); }

@media (max-width: 900px) {
  .perm-wrap { grid-template-columns: 1fr; }
  .perm-rail { display: flex; flex-wrap: wrap; padding: 6px; }
  .perm-r { border-left: 0; border-bottom: 3px solid transparent; }
  .perm-r.on { border-left: 0; border-bottom-color: var(--saffron); }
}

/* The sentence under a checkbox that needs one. */
.fld-h { display: block; margin-top: 3px; color: var(--g70); font-size: 11.5px; line-height: 1.45; }

/* Destructive actions must not look like ordinary ones. */
.b-danger {
  display: inline-flex; align-items: center; gap: 8px;
  background: #fff; color: var(--red70); border: 1px solid var(--red);
  padding: 10px 16px; font-size: 13.5px; font-weight: 600;
}
.b-danger:hover { background: var(--red); color: #fff; }

/* Audit before/after diff. */
.diff { display: grid; grid-template-columns: 1fr 1fr; gap: 1px; background: var(--g20); border: 1px solid var(--g20); font-family: var(--mono); font-size: 11.5px; }
.diff-c { background: #fff; padding: 11px 13px; overflow-x: auto; }
.diff-c.before { background: var(--red10); }
.diff-c.after  { background: var(--green10); }
@media (max-width: 700px) { .diff { grid-template-columns: 1fr; } }

/* ---------------------------------------------------------------------------
   Offline state. The pending-sync badge has to be visible without being
   alarming — a venue on 2G is normal, not an error.
--------------------------------------------------------------------------- */
.off-badge {
  display: inline-flex; align-items: center; gap: 7px;
  background: var(--amber10); color: var(--amber70);
  border: 1px solid var(--amber); padding: 4px 10px;
  font-size: 11.5px; font-weight: 600;
}
.off-badge[hidden] { display: none; }

/* Staleness note under dashboards fed by 60s aggregates (ADR-003). Saying
   "as of 09:41" is honest; implying live data is not. */
.stale { font-size: 11px; color: var(--g70); margin-top: 8px; display: flex; align-items: center; gap: 6px; }

/* Print: certificates and result sheets get printed at venues. */
@media print {
  .hdr, .nav, .foot, .lang, .b-pri, .b-sec, .b-sm { display: none !important; }
  .body { display: block; }
  .main { padding: 0; }
  .cert { border: none; }
}

/* ---------------------------------------------------------------------------
   The header brand is a link to "/", and an <a> with no colour of its own
   inherits the browser's :visited purple -- which turned the masthead magenta
   as soon as anyone had been to the home page. Pin it.
--------------------------------------------------------------------------- */
.hdr-brand, .hdr-brand:visited, .hdr-brand:hover,
.hdr-name, .hdr-brand .hdr-name { color: #fff; text-decoration: none; }
.hdr-brand:hover .hdr-name { color: var(--g30); }

/* --- expert assessment sheet -------------------------------------------- */
/* A tap target, not a dropdown: an expert scores this at the side of a track,
   and a select costs two taps and hides the scale while choosing. */
.scale-row{display:flex;gap:6px;flex-wrap:wrap}
.scale-opt{position:relative;display:inline-flex}
.scale-opt input{position:absolute;opacity:0;width:100%;height:100%;margin:0;cursor:pointer}
.scale-opt span{display:flex;align-items:center;justify-content:center;
  width:38px;height:38px;border:1px solid var(--g30,#c6c6c6);background:#fff;
  font-size:14px;font-weight:600;color:#525252;transition:all .12s}
.scale-opt input:checked + span{background:#0f62fe;border-color:#0f62fe;color:#fff}
.scale-opt input:focus-visible + span{outline:2px solid #0f62fe;outline-offset:2px}
.scale-opt:hover span{border-color:#0f62fe}
.tag.p{background:#f6f2ff;color:#6929c4}

/* --- sports assignment ---------------------------------------------------- */
.scope-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(190px,1fr));
  gap:8px;margin:12px 0}
.scope-box{display:flex;align-items:center;gap:9px;padding:10px 12px;
  border:1px solid var(--g20,#e0e0e0);background:#fff;cursor:pointer;font-size:13.5px}
.scope-box:hover{border-color:#0f62fe}
.scope-box input{margin:0;accent-color:#0f62fe;width:16px;height:16px}
.scope-box:has(input:checked){border-color:#0f62fe;background:#edf5ff}
.scope-group{border:1px solid var(--g20,#e0e0e0);margin:8px 0;background:#fff}
.scope-group summary{padding:11px 14px;font-weight:600;font-size:13.5px;cursor:pointer}
.scope-group summary:hover{background:var(--g10,#f4f4f4)}
.scope-group .scope-grid{padding:0 14px 14px}
.codeblock{background:var(--g100,#161616);color:#f4f4f4;padding:12px 14px;overflow-x:auto;
  font-family:var(--mono,monospace);font-size:12.5px;line-height:1.6;margin:10px 0}

/* --- DNS / DNF / DQ ------------------------------------------------------- */
/* One tap each, all three visible without opening anything. The Figma shows
   them as solid pills that fill when chosen. */
.outcome{display:flex;gap:4px;align-items:center;flex-wrap:wrap}
.outcome-opt{position:relative;display:inline-flex}
.outcome-opt input{position:absolute;opacity:0;width:100%;height:100%;margin:0;cursor:pointer}
.outcome-opt span{display:flex;align-items:center;justify-content:center;min-width:44px;
  height:32px;padding:0 10px;border:1px solid var(--g30,#c6c6c6);background:#fff;
  font-size:11.5px;font-weight:600;color:#525252;transition:all .12s}
.outcome-opt input:focus-visible + span{outline:2px solid #0f62fe;outline-offset:2px}
.outcome-fin input:checked + span{background:#24a148;border-color:#24a148;color:#fff}
.outcome-dns input:checked + span{background:#8d8d8d;border-color:#8d8d8d;color:#fff}
.outcome-dnf input:checked + span{background:#b28600;border-color:#b28600;color:#fff}
.outcome-dq  input:checked + span{background:#da1e28;border-color:#da1e28;color:#fff}
/* The reason only matters for a DQ, so it only appears for one. */
.outcome-note{display:none;width:190px;background:var(--g10,#f4f4f4);border:none;
  border-bottom:1px solid var(--g50,#8d8d8d);padding:7px 10px;font-size:12.5px}
.outcome:has(.outcome-dq input:checked) .outcome-note{display:block}

/* ===========================================================================
   Leap to Podium re-skin — Figma "KHEL Mahakumbh", 15 Sep 2026
   ---------------------------------------------------------------------------
   The Carbon shell underneath is unchanged; this layer restyles it. Saffron
   for action, indigo for the state's own chrome, a white masthead instead of
   a black one, and navigation as a grid of tiles rather than a left rail.

   Everything here is a colour, a border or a layout box. No component was
   rebuilt for the re-skin, so a screen that worked before the re-skin works
   after it -- which is the only way a look-and-feel change is safe to make
   the week of a demo.
   =========================================================================== */

:root {
  --saffron: #d14115;
  --saffron-d: #a93310;
  --saffron-10: #fdf3ec;
  --saffron-20: #f6dbc9;
  --indigo: #3e59b4;
  --indigo-d: #31479a;
  --indigo-10: #eef1fb;
  --page: #f7f9fc;
  --hdr: 60px;
}

/* A short page must still push the footer to the bottom of the window, or
   the state's own footer floats in the middle of a white screen. */
/* A figure row is followed by whatever the screen shows next -- a section
   heading brings its own space, a table does not. */
.kpis { margin-bottom: 18px; }

body { background: var(--page); min-height: 100vh; display: flex; flex-direction: column; }
.body, .lp { flex: 1 0 auto; }
.foot { flex-shrink: 0; }

/* --- masthead ------------------------------------------------------------ */

.hdr {
  background: #fff;
  color: var(--g100);
  border-bottom: 1px solid var(--g20);
  padding: 0 20px;
  gap: 14px;
}
/* 50 x 50, as specified on 22 Sep. The emblem is the state's, and it was
   being drawn at 30px beside a wordmark sized for something larger. */
.hdr-mark { display: inline-flex; align-items: center; }
.hdr-mark img, .hdr-mark svg { width: 50px; height: 50px; object-fit: contain; }
.hdr-brand { gap: 10px; }
.hdr-name { display: inline-flex; align-items: baseline; gap: 6px; font-weight: 400; }
.hdr-name b { font-size: 18px; font-weight: 800; letter-spacing: -.01em; color: var(--g100); }
.hdr-name em { font-size: 18px; font-weight: 800; font-style: normal;
  letter-spacing: -.01em; color: var(--saffron); }
.hdr-name i { font-size: 15px; font-style: normal; font-weight: 400; color: var(--g60); }

/* A branded element that is also a link needs its colour pinned explicitly,
   or it inherits :visited purple the moment anyone has been to the home page
   (CLAUDE.md §17.4). */
.hdr-brand, .hdr-brand:visited, .hdr-brand:hover,
.hdr-name, .hdr-brand .hdr-name { color: var(--g100); text-decoration: none; }
.hdr-brand:hover em { color: var(--saffron-d); }
.hdr-brand:hover b { color: var(--g80); }
.hdr-rule { background: var(--g30); }
.hdr-who { color: var(--g70); }
.hdr-btn { color: var(--g70); opacity: 1; border: 1px solid var(--g30); background: #fff; }
.hdr-btn:hover { border-color: var(--saffron); color: var(--saffron); }
.hdr a:focus-visible, .hdr button:focus-visible { outline-color: var(--saffron); }

.hdr-user { display: inline-flex; align-items: center; gap: 9px; white-space: nowrap; }
.hdr-av, .hero-av {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: 4px;
  background: var(--saffron-10); color: var(--saffron-d);
  font-size: 11.5px; font-weight: 700; letter-spacing: .02em;
}
.hdr-un { font-size: 13px; font-weight: 500; color: var(--g90); }

.hdr .lang a button { color: var(--g70); }
.hdr .lang a button[aria-current="true"] { background: var(--saffron); color: #fff; }

/* --- breadcrumb ---------------------------------------------------------- */

.crumb {
  background: var(--saffron-10);
  border-bottom: 1px solid var(--saffron-20);
  padding: 9px 28px;
  font-size: 12.5px;
}
.crumb nav { display: flex; align-items: center; gap: 8px; }
.crumb a { color: var(--g70); text-decoration: none; }
.crumb a:hover { color: var(--saffron-d); text-decoration: underline; }
.crumb span { color: var(--g40); }
.crumb b { color: var(--g90); font-weight: 600; }

/* --- profile band -------------------------------------------------------- */

.hero {
  display: flex; align-items: center; gap: 14px;
  padding: 14px 28px;
  background: linear-gradient(180deg, var(--saffron-10) 0%, #fff 100%);
  border-bottom: 1px solid var(--saffron-20);
  position: relative; overflow: hidden;
}
.hero-av { width: 46px; height: 46px; font-size: 15px; border-radius: 6px; }
.hero-n { font-size: 17px; font-weight: 600; color: var(--g100); line-height: 1.2; }
.hero-r { font-size: 12.5px; color: var(--g60); margin-top: 3px; }
/* The Figma's illustration band, as a running track rather than a picture:
   nothing in the shell should cost a request on a 2G connection, and an
   air-gapped install has nowhere to fetch an image from. Repeating lanes
   fading out to the left, which is what the artwork reads as at a glance. */
.hero-art {
  position: absolute; inset: 0 0 0 auto; width: 46%; pointer-events: none;
  background: repeating-linear-gradient(
    100deg, var(--saffron-10) 0 22px, transparent 22px 24px);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 65%);
  mask-image: linear-gradient(90deg, transparent, #000 65%);
}
/* An uploaded band is sized to the panel, not to its own pixels. It was
   drawn at its intrinsic height and clipped, so the same artwork looked
   different on a tall page and a short one (22 Sep). */
.hero-art.has-img {
  width: 58%;
  background-size: cover; background-position: right center;
  background-repeat: no-repeat;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 40%);
  mask-image: linear-gradient(90deg, transparent, #000 40%);
}

/* --- navigation ----------------------------------------------------------
   Two shapes, following the design: a pill bar for a surface that fits in one
   row, a collapsible rail for the admin console, which does not. */

/* The pill bar carries the design's warm band. It was white, which is what
   "missing background color" was pointing at on 22 Sep: in the Figma the
   navigation and the profile band read as one tinted strip under the
   masthead, and ours read as two white rows. */
.pills {
  display: flex; gap: 8px; flex-wrap: wrap;
  background: var(--saffron-10); border-bottom: 1px solid var(--saffron-20);
  padding: 10px 28px;
}
.pill {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 14px; border-radius: 8px;
  border: 1px solid transparent; background: transparent;
  font-size: 13px; font-weight: 600; color: var(--g70); text-decoration: none;
  white-space: nowrap;
}
.pill:hover { background: var(--g10); color: var(--g100); }
.pill.on { background: var(--saffron); border-color: var(--saffron); color: #fff; }
.pill.on .nav-ico { color: #fff; }
.pill:focus-visible { outline: 2px solid var(--g90); outline-offset: 2px; }
.pill .nav-ico { color: var(--g60); flex-shrink: 0; }

.rail {
  width: 250px; flex-shrink: 0; background: #fff;
  border-right: 1px solid var(--g20); padding: 10px 0 30px;
}
.rail-g { border-bottom: 1px solid var(--g20); }
.rail-s {
  display: flex; align-items: center; gap: 10px; cursor: pointer;
  padding: 15px 18px; list-style: none;
  font-size: 13.5px; font-weight: 600; color: var(--g90);
  background: #f7f9fc;
}
.rail-s::-webkit-details-marker { display: none; }
.rail-s span { flex: 1; min-width: 0; }
.rail-s:hover { background: var(--g10); }
.rail-c { color: var(--g60); transition: transform .15s; flex-shrink: 0; }
.rail-g[open] > .rail-s .rail-c { transform: rotate(180deg); }
.rail-i { padding: 4px 0 10px; }
.rail-l {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 18px 9px 22px; font-size: 13px; color: var(--g70);
  text-decoration: none; border-left: 3px solid transparent;
}
.rail-l i {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--g30); flex-shrink: 0;
}
.rail-l:hover { background: var(--g10); color: var(--g100); }
.rail-l.on {
  background: var(--saffron-10); border-left-color: var(--saffron);
  color: var(--g100); font-weight: 600;
}
.rail-l.on i { background: var(--saffron); }

/* --- body ---------------------------------------------------------------- */

.body { display: flex; min-height: 0; align-items: stretch; }
.main { max-width: none; padding: 22px 28px 40px; }

/* --- filter bar ---------------------------------------------------------- */

.filters {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px;
  background: #fff; border: 1px solid var(--g20); border-radius: 8px;
  padding: 14px; margin-bottom: 16px;
}
.filters .fld { margin: 0; min-width: 150px; flex: 0 1 auto; }
.filters .fld label { font-size: 10.5px; }
.filters-a { display: flex; gap: 8px; align-items: flex-end; }
.filters-q { flex: 1 1 240px; min-width: 200px; }
.filters-a { flex-shrink: 0; }
/* A row that opens something -- a sport opening its disciplines. Coloured
   explicitly, visited or not: a bare link is the browser's blue, then purple. */
.row-link, .row-link:visited { color: var(--indigo); font-weight: 600; text-decoration: none; }
.row-link:hover { color: var(--indigo-d); text-decoration: underline; }
/* The download pair on a table with no filter bar of its own. */
.exp-acts { justify-content: flex-end; margin: 4px 0 12px; }

/* --- buttons ------------------------------------------------------------- */

.b-pri { background: var(--saffron); border-color: var(--saffron); color: #fff; }
.b-pri:hover { background: var(--saffron-d); border-color: var(--saffron-d); }

/* The filter-bar actions. They carry their own box rather than leaning on
   .b-pri, because two of the three are links -- an <a> inherits none of a
   button's padding, and one that is coloured but unpadded reads as broken. */
.b-search, .b-clear, .b-excel {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  height: 38px; padding: 0 18px; border-radius: 6px;
  font-size: 13px; font-weight: 600; line-height: 1;
  border: 1px solid transparent; cursor: pointer; text-decoration: none;
  white-space: nowrap;
}
.b-search { background: var(--saffron); border-color: var(--saffron); color: #fff; }
.b-search:hover { background: var(--saffron-d); border-color: var(--saffron-d); }
.b-clear { background: var(--indigo); border-color: var(--indigo); color: #fff; }
.b-clear:hover, .b-clear:visited { background: var(--indigo-d); border-color: var(--indigo-d); color: #fff; }
.b-excel { background: #fff; color: var(--saffron); border-color: var(--saffron); }
.b-excel:hover, .b-excel:visited { color: var(--saffron); }
.b-excel:hover { background: var(--saffron-10); }
.b-search:focus-visible, .b-clear:focus-visible, .b-excel:focus-visible {
  outline: 2px solid var(--g90); outline-offset: 2px;
}

/* --- tables -------------------------------------------------------------- */

.card { border-radius: 8px; overflow: hidden; }
.tblwrap { border-radius: 8px; }
thead th { background: #f0f5fc; color: var(--g80); }

/* --- numbered pagination ------------------------------------------------- */

.pager {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  padding: 12px 14px; background: #fff; border-top: 1px solid var(--g20);
}
.pager-p {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 32px; height: 32px; padding: 0 8px;
  border: 1px solid var(--g20); border-radius: 6px; background: #fff;
  font-size: 12px; font-weight: 600; color: var(--g80); text-decoration: none;
}
.pager-p:hover { border-color: var(--indigo); color: var(--indigo); }
.pager-p.on { background: var(--g90); border-color: var(--g90); color: #fff; }
.pager-p[aria-disabled="true"] { opacity: .4; pointer-events: none; }
.pager-g { color: var(--g50); padding: 0 2px; }
.pager-r { margin-left: auto; display: flex; align-items: center; gap: 8px;
  font-size: 12px; color: var(--g70); }
.pager-r select { width: auto; min-width: 68px; }

/* --- footer -------------------------------------------------------------- */

.foot {
  margin-top: 0; padding: 14px 28px; border-top: 0;
  background: var(--indigo); color: #fff;
}
.foot-o { color: #fff; font-weight: 500; }
.foot-d { background: rgba(255, 255, 255, .4); }
.foot-m { color: rgba(255, 255, 255, .75); }

/* --- narrow screens ------------------------------------------------------ */

@media (max-width: 900px) {
  /* The rail becomes a strip above the page rather than a drawer: a drawer
     needs JavaScript to open, and this console is used on venue laptops with
     whatever browser the district had. */
  .body { display: block; }
  .rail { width: auto; border-right: 0; border-bottom: 1px solid var(--g20); padding-bottom: 6px; }
}

@media (max-width: 720px) {
  .hdr { padding: 0 12px; gap: 8px; }
  .hdr-name i, .hdr-un { display: none; }
  .crumb, .hero, .pills, .main, .foot { padding-left: 14px; padding-right: 14px; }
  .pills { gap: 6px; overflow-x: auto; flex-wrap: nowrap; }
  .filters-q { margin-left: 0; width: 100%; }
}

/* --- masthead badges ------------------------------------------------------ */

.live { background: var(--saffron-10); border-color: var(--saffron-20); color: var(--saffron-d); }
.off-badge { background: var(--indigo); color: #fff; }

/* --- search --------------------------------------------------------------- */

.search {
  border: 1px solid var(--g20); border-radius: 8px; border-bottom-width: 1px;
  padding: 9px 12px;
}
.search:focus-within { border-color: var(--saffron); border-bottom-color: var(--saffron); }
.search .b-sm { border-color: var(--saffron); background: var(--saffron); color: #fff; }
.search .b-sm:hover { background: var(--saffron-d); border-color: var(--saffron-d); }

/* --- landing page --------------------------------------------------------- */

.lp { max-width: 1180px; margin: 0 auto; padding: 0 28px 48px; }

.lp-hero {
  position: relative; overflow: hidden;
  padding: 52px 0 40px; border-bottom: 1px solid var(--g20);
}
.lp-hero-t { position: relative; z-index: 1; max-width: 640px; }
.lp-h {
  font-size: 44px; font-weight: 300; line-height: 1.1; color: var(--g100);
  letter-spacing: -.02em; margin: 0;
}
.lp-s { font-size: 16px; color: var(--g70); line-height: 1.6; margin: 16px 0 0; max-width: 560px; }
.lp-date {
  display: inline-block; margin-top: 22px; padding: 8px 16px;
  background: var(--saffron-10); border: 1px solid var(--saffron-20);
  border-radius: 999px; font-size: 13px; font-weight: 600; color: var(--saffron-d);
}
.lp-art {
  position: absolute; inset: 0 -28px 0 auto; width: 42%; pointer-events: none;
  background: repeating-linear-gradient(100deg, var(--saffron-10) 0 26px, transparent 26px 29px);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 70%);
  mask-image: linear-gradient(90deg, transparent, #000 70%);
}

.lp-stats {
  display: grid; gap: 12px; margin: 26px 0 0;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
}
.lp-stat {
  background: #fff; border: 1px solid var(--g20); border-radius: 8px;
  border-top: 3px solid var(--indigo); padding: 16px 18px;
}
.lp-stat-v { font-size: 28px; font-weight: 600; color: var(--g100); line-height: 1.1; }
.lp-stat-l {
  font-size: 11px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
  color: var(--g60); margin-top: 8px;
}

.lp-roles {
  display: grid; gap: 14px; margin-top: 30px;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
}
.lp-role {
  display: flex; flex-direction: column; gap: 6px;
  background: #fff; border: 1px solid var(--g20); border-radius: 8px; padding: 20px;
}
.lp-role-t { font-size: 16px; font-weight: 600; color: var(--g100); }
.lp-role-s { font-size: 13px; color: var(--g60); line-height: 1.5; flex: 1; }
.lp-role-a { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 12px; }
.lp-role-b {
  display: inline-flex; align-items: center; justify-content: center;
  height: 38px; padding: 0 18px; border-radius: 6px;
  border: 1px solid var(--g30); background: #fff; color: var(--g80);
  font-size: 13px; font-weight: 600; text-decoration: none;
}
.lp-role-b:hover, .lp-role-b:visited { color: var(--g80); }
.lp-role-b:hover { border-color: var(--indigo); color: var(--indigo); }

@media (max-width: 720px) {
  .lp { padding: 0 14px 32px; }
  .lp-h { font-size: 32px; }
  .lp-art { display: none; }
}

/* --- the sign-in lockup ---------------------------------------------------
   Two lines, with the campaign tagline rather than "Digital Platform". The
   signed-in header keeps the one-line form; this is the front door. */

.hdr-signin { height: auto; padding: 14px 28px; align-items: flex-start; }
.hdr-lock { display: flex; flex-direction: column; gap: 2px; }
.hdr-tag { font-size: 17px; font-weight: 400; color: var(--g80); line-height: 1.2; }
.hdr-tag i { font-style: normal; color: var(--indigo); }

@media (max-width: 720px) {
  .hdr-signin { padding: 12px 14px; }
  .hdr-tag { font-size: 14px; }
}

/* --- the sign-in screen ----------------------------------------------------
   Split: artwork left, the form right. One screen for every kind of
   credential, with a role picker deciding which fields show. */

/* Half and half, as the design is: the artwork panel and the form column are
   the same width in the Figma frame, and 5fr/7fr left the illustration in a
   narrow strip beside a stretched form -- "image to be resized as per FIGMA",
   "realign to fix the white spaces" (22 Sep). */
.si { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); min-height: 0; }
/* The artwork half.
   The design fills this with an illustration of athletes over Gujarat
   landmarks. Until that asset is exported from Figma the panel carries the
   running-track motif the rest of the shell uses -- and it is bottom-anchored
   and unbordered, because a bordered empty rectangle reads as a component
   that failed to load, while a wash reads as a background. */
/* The artwork fills its column. It was sized to its own intrinsic height and
   sat as a small picture in a tall white panel -- "image size to be fixed",
   21 Sep. The portraits keep their band at the top; the illustration takes
   whatever is left. */
.si-art { position: relative; min-height: 520px; display: flex; flex-direction: column; overflow: hidden; }
/* The illustration fills whatever the portraits leave. It is positioned
   absolutely inside its own box rather than sized with height:100%, because a
   percentage height against an auto-height flex parent resolves to auto and
   the picture fell back to its intrinsic size -- a small illustration adrift
   in a tall white panel. */
.si-art-fill {
  position: relative; flex: 1 1 auto; min-height: 320px;
  /* The wash behind the artwork, so the band `contain` leaves reads as the
     page's own background rather than as an image that failed to fill. */
  background: linear-gradient(180deg, #fff 0%, var(--saffron-10) 100%);
}
.si-art-fill .si-art-img { position: absolute; inset: 0; }
/* Left bottom, as the client specified: the artwork is a composition with
   its weight in the lower-left corner, and centring it cropped the athletes
   out of frame at narrow widths. */
/* Contained, not covered. The design team re-exports this panel and the shape
   changes with each export -- the 22 Sep upload was landscape into a portrait
   slot, and `cover` was slicing 10% off its sides, athletes included. The
   whole composition shows now whatever shape arrives, anchored to its own
   bottom edge so the ground line stays at the foot of the panel.
   Same rule as .si-vip img: cover is for scenery with no subject. */
.si-art-img { display: block; width: 100%; height: 100%; object-fit: contain; object-position: center bottom; }
/* The fallback, for a slot nobody has filled yet. Bottom-anchored and
   unbordered: a bordered empty rectangle reads as a component that failed to
   load, a wash reads as a background. */
.si-art-fallback {
  flex: 1 1 auto; min-height: 320px;
  background:
    repeating-linear-gradient(100deg, var(--saffron-20) 0 34px, transparent 34px 40px),
    linear-gradient(180deg, #fff 0%, var(--saffron-10) 100%);
  -webkit-mask-image: linear-gradient(180deg, transparent, #000 45%);
  mask-image: linear-gradient(180deg, transparent, #000 45%);
}

/* The portraits above the artwork. */
/* The portrait band is a band, not the panel. Square portraits at the full
   column width took two thirds of the artwork panel; the design gives them a
   shallow strip across the top on a tinted card. */
.si-vips { display: flex; gap: 12px; padding: 18px 18px 6px; }
.si-vip {
  flex: 1; margin: 0; min-width: 0;
  border-radius: 8px; padding: 12px 10px 14px; background: var(--saffron-10);
}
.si-vip:nth-child(2) { background: #fcf2d4; }
.si-vip:nth-child(3) { background: #d9e8f8; }
/* NEVER crop a portrait.
   These are photographs of named people -- the Chief Minister, the Deputy
   Chief Minister and the Minister of State. `object-fit: cover` fills the box
   by cutting off whatever does not fit, and on 22 Sep it cut the tops of their
   heads off on the state's own sign-in screen.
   `contain` shows the whole photograph whatever shape it was uploaded in, and
   letterboxes onto the card's own white instead. A slightly smaller portrait
   is a design compromise; a beheaded one is an insult.
   Rule: object-fit: cover is for scenery. A photograph of a person, a logo, or
   anything with a subject that must stay whole, takes `contain`. */
.si-vip img {
  width: 100%; height: 180px; object-fit: contain; object-position: center;
  border-radius: 6px; display: block; background: #fff;
}
.si-vip figcaption { margin-top: 10px; text-align: center; line-height: 1.45; }
.si-vip figcaption b { display: block; font-size: 13px; color: var(--g100); }
.si-vip figcaption span { display: block; font-size: 11.5px; color: var(--g60); margin-top: 4px; }

/* --- branding image management -------------------------------------------- */

.img-grid {
  display: grid; gap: 14px; margin-top: 18px; align-items: start;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
}
.img-card { border-radius: 8px; }
/* The slot name is the card's own heading and the design sets it in the brand
   colour, which is also how a reader tells one card from the next in a grid of
   eight. */
.img-t { font-size: 15px; font-weight: 600; color: var(--saffron-d); }
.img-h { font-size: 12px; color: var(--g60); margin-top: 4px; line-height: 1.45; min-height: 34px; }

/* The drop area. It shows whatever is in the slot today, with the Browse
   control over it; an empty slot shows the control alone on a dashed ground,
   which is the design's empty state. */
.img-drop {
  position: relative; margin-top: 12px;
  border: 1.5px dashed var(--g30); border-radius: 8px; background: var(--g10);
  min-height: 150px; display: flex; align-items: center; justify-content: center;
  overflow: hidden;
}
.img-drop-img { max-width: 100%; max-height: 150px; object-fit: contain; }
.img-drop-c {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px;
}
/* With an image in the slot the control moves out of the way rather than
   disappearing: a reader has to be able to see how to replace what is there
   without discovering a hover. */
.img-drop:has(.img-drop-img) .img-drop-c { inset: auto 0 0 0; padding: 8px; }
.img-drop:has(.img-drop-img) .img-drop-c::before {
  content: ""; position: absolute; inset: 0; background: linear-gradient(180deg, transparent, rgba(255, 255, 255, .92) 55%);
}
.img-drop:has(.img-drop-img) .img-drop-i { display: none; }
.img-drop-i {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  width: 42px; height: 42px; border-radius: 50%;
  border: 1px solid var(--indigo); color: var(--indigo); background: #fff;
}
/* The file input is the label's target and nothing else: it is reached by
   clicking Browse File or by tabbing to it, so it is hidden from layout
   without being hidden from the keyboard. */
.img-file {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.b-browse {
  position: relative; cursor: pointer;
  display: inline-flex; align-items: center;
  padding: 7px 14px; border-radius: 6px; border: 1px solid var(--indigo);
  background: var(--indigo); color: #fff; font-size: 12.5px; font-weight: 600;
}
.b-browse:hover { background: #1a3fb8; border-color: #1a3fb8; }
.img-file:focus-visible + .img-drop-c .b-browse,
.img-drop:focus-within .b-browse { outline: 2px solid var(--saffron); outline-offset: 2px; }

.img-meta { margin-top: 8px; font-size: 11.5px; color: var(--g60); }
.img-dot { color: var(--g30); margin: 0 5px; }

/* The file row: a tick, what the file is, and a bin. */
.img-row {
  display: flex; align-items: center; gap: 8px;
  margin-top: 10px; font-size: 11.5px; color: var(--green70);
}
.img-row-live { margin-top: 12px; border-top: 1px solid var(--g20); padding-top: 12px; }
.img-row-ok { display: inline-flex; color: var(--green); flex: 0 0 auto; }
.img-row-n { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.img-row-x {
  flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; border-radius: 6px;
  background: none; border: 0; cursor: pointer; color: var(--red);
}
.img-row-x:hover { background: #fde9e7; }
.si-form { padding: 34px 34px 28px; min-width: 0; background: #fff; }
/* The whole opening screen sits on white. It carried the page's pale wash,
   which the client compared against the Figma on 20 Sep. */
.si { background: #fff; }

.si-h {
  font-size: 40px; font-weight: 300; letter-spacing: -.02em;
  color: var(--g100); line-height: 1.1; margin: 0;
}
.si-h b { font-weight: 700; color: var(--indigo); }
.si-s { font-size: 16.5px; color: var(--g70); line-height: 1.6; margin: 14px 0 0; max-width: 52ch; }

.si-chips { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 20px; }
.si-chip {
  display: inline-flex; align-items: center; gap: 8px;
  border: 1px solid var(--indigo); border-radius: 8px;
  padding: 12px 17px; font-size: 14.5px; color: var(--g80); background: #fff;
}
.si-chip b { color: var(--indigo); font-weight: 700; }

.si-head { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 26px; }
.si-t { font-size: 21px; font-weight: 600; color: var(--g100); }
.si-n { font-size: 13.5px; color: var(--g60); margin-top: 3px; }

/* The role picker, the two credential boxes and the actions all share one
   left edge and one right edge. */
.si-fields .fld label, .si-role .fld label { font-size: 13.5px; }
.si-fields input, .si-role select { font-size: 14.5px; padding: 12px 14px; }
.si-role { margin-top: 16px; max-width: 100%; }
.si-role .fld { margin: 0; }
.si-fields { margin-top: 14px; }
.si-fields .fg { gap: 16px; }
.si-acts { display: flex; gap: 10px; margin-top: 18px; }
.fld-submit { display: flex; align-items: flex-end; }

/* An action sitting inside a field — Send OTP, Resend OTP. */
.fld-in { position: relative; display: flex; align-items: stretch; }
.fld-in input { flex: 1; padding-right: 108px; }
.fld-act {
  position: absolute; right: 8px; top: 50%; transform: translateY(-50%);
  background: none; border: 0; cursor: pointer;
  font-size: 12.5px; font-weight: 600; color: var(--saffron);
  padding: 4px 6px;
}
.fld-act:hover { color: var(--saffron-d); text-decoration: underline; }

.si-help {
  display: flex; align-items: center; gap: 8px;
  margin-top: 18px; font-size: 14px; color: var(--g70);
}
.si-help span {
  display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; border-radius: 50%;
  border: 1px solid var(--g30); font-size: 11px; font-weight: 700; color: var(--g60);
}
.si-help a { color: var(--saffron); font-weight: 600; text-decoration: none; }
.si-help a:hover { text-decoration: underline; }

/* Three across, two rows -- the design's arrangement, and the one that keeps
   the individual figures on one line and the team figures on the next. */
.si-stats {
  display: grid; gap: 12px; margin-top: 28px;
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
.si-stat { border-radius: 8px; padding: 16px 18px; }
.si-stat-v { font-size: 30px; font-weight: 700; color: var(--g100); line-height: 1.1; }
.si-stat-l { font-size: 13px; color: var(--g70); margin-top: 6px; }
.si-stat.peach { background: #fde8dc; }
.si-stat.cream { background: #fcf2d4; }
.si-stat.sky   { background: #d9e8f8; }
.si-stat.lilac { background: #eee0fb; }
.si-stat.rose  { background: #fbdde4; }
.si-stat.sand  { background: #fbe0c8; }

@media (max-width: 940px) {
  .si { grid-template-columns: 1fr; }
  .si-art { display: none; }
  .si-form { padding: 22px 14px; }
  .si-h { font-size: 30px; }
}

/* --- the athlete's dashboard ---------------------------------------------- */

.me-cols { display: grid; gap: 22px; grid-template-columns: 1fr 1fr; align-items: start; }

/* One scored dimension, or one certificate. */
.pw { padding: 11px 0; border-bottom: 1px solid var(--g20); }
.pw:last-of-type { border-bottom: 0; }
.pw-t { display: flex; align-items: baseline; gap: 10px; font-size: 13.5px; }
.pw-s {
  font-size: 12px; font-weight: 700; color: var(--indigo);
  background: var(--indigo-10); border-radius: 4px; padding: 2px 8px;
}
.pw-h { font-size: 11.5px; color: var(--g60); margin-top: 3px; line-height: 1.45; }

/* One message the platform sent. */
.msg { padding: 10px 0; border-bottom: 1px solid var(--g20); }
.msg:last-of-type { border-bottom: 0; }
.msg-w { font-size: 11px; color: var(--g50); letter-spacing: .02em; }
.msg-t { font-size: 13px; color: var(--g90); margin-top: 3px; line-height: 1.5; }

.pill-d {
  display: inline-block; font-size: 11.5px; font-weight: 600;
  background: var(--g10); color: var(--g70); padding: 3px 9px; border-radius: 4px;
}

@media (max-width: 900px) { .me-cols { grid-template-columns: 1fr; } }

/* --- the athlete's expert feedback ---------------------------------------- */

.fb-pills { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 12px; }
.fb-p { margin: 6px 0 0; font-size: 13.5px; line-height: 1.6; color: var(--g90); }
.fb-by {
  margin-top: 18px; padding-top: 12px; border-top: 1px solid var(--g20);
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
}
.fb-by b { font-size: 13px; color: var(--g90); }
.fb-by span { font-size: 11.5px; color: var(--g50); font-family: var(--mono); }

.si-hint { margin: 12px 0 0; font-size: 12.5px; color: var(--g60); line-height: 1.55; max-width: 62ch; }

/* --- result capture ------------------------------------------------------- */

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

.cap-rail { position: sticky; top: 12px; align-self: start; }
.cap-ev {
  display: grid; grid-template-columns: 1fr auto; column-gap: 10px;
  padding: 11px 13px; margin-bottom: 8px;
  background: #fff; border: 1px solid var(--g20); border-radius: 8px;
  text-decoration: none; color: inherit;
}
.cap-ev:hover { border-color: var(--indigo); }
.cap-ev.on { background: var(--saffron-10); border-color: var(--saffron); }
.cap-ev.done { opacity: .72; }
/* Title and sub-line occupy the first column; the count sits in the second,
   top-aligned. It used to be absolutely positioned, which was fine while an
   event was called "100 m" and collided the moment the full name -- sport,
   discipline, age category, gender -- wrapped to two lines. */
.cap-ev-t { grid-column: 1; font-size: 13px; font-weight: 600; color: var(--g100); }
.cap-ev-s { grid-column: 1; font-size: 11.5px; color: var(--g60); margin-top: 3px; }
.cap-ev-p {
  grid-column: 2; grid-row: 1; align-self: start; white-space: nowrap;
  font-size: 11px; font-weight: 700; color: var(--g60); font-family: var(--mono);
}

.cap-hd { display: flex; align-items: flex-start; gap: 14px; }
.cap-hd-t { font-size: 20px; font-weight: 600; color: var(--g100); }
.cap-hd-s { font-size: 12.5px; color: var(--g60); margin-top: 4px; }

.cap-tools { margin: 14px 0; }
.cap-tools input {
  width: 100%; max-width: 380px; background: #fff;
  border: 1px solid var(--g20); border-radius: 8px; padding: 10px 13px; font-size: 13px;
}
.cap-tools input:focus { outline: none; border-color: var(--saffron); }

.cap-cols { display: grid; grid-template-columns: minmax(0, 1fr) 260px; gap: 16px; align-items: start; }
.cap-tbl { width: 100%; border-collapse: collapse; }
.cap-tbl th { background: #f0f5fc; }
.cap-pos {
  font-family: var(--mono); font-weight: 700; font-size: 14px;
  color: var(--g90); width: 52px; text-align: center;
}
.cap-in {
  width: 118px; background: var(--g10); border: 1px solid transparent;
  border-bottom: 1px solid var(--g50); padding: 8px 10px; font-family: var(--mono);
}
.cap-in:focus { outline: none; border-color: var(--saffron); background: #fff; }

.cap-foot {
  padding: 11px 16px; border-top: 1px solid var(--g20);
  font-size: 12px; color: var(--g60);
}
.cap-foot-d { color: var(--g30); margin: 0 7px; }

.cap-live-l { list-style: none; margin: 0; padding: 0; }
.cap-live-i {
  display: flex; align-items: baseline; gap: 9px;
  padding: 8px 0; border-bottom: 1px solid var(--g20); font-size: 13px;
}
.cap-live-i:last-child { border-bottom: 0; }
.cap-live-p {
  min-width: 22px; height: 22px; border-radius: 4px;
  background: var(--indigo-10); color: var(--indigo);
  font-size: 11.5px; font-weight: 700; font-family: var(--mono);
  display: inline-flex; align-items: center; justify-content: center;
}
.cap-live-n { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.cap-live-m { font-family: var(--mono); font-size: 12px; color: var(--g70); }
.cap-live-e { margin: 0; font-size: 12px; color: var(--g60); line-height: 1.5; }

.cap-acts { display: flex; gap: 10px; margin-top: 18px; }

@media (max-width: 1100px) { .cap-cols { grid-template-columns: 1fr; } }
@media (max-width: 900px) {
  .cap { grid-template-columns: 1fr; }
  .cap-rail { position: static; }
}

/* --- the athlete's certificates -------------------------------------------- */

.cert-c { margin-bottom: 12px; }
.cert-h { display: flex; align-items: flex-start; gap: 12px; }
.cert-t { font-size: 15px; font-weight: 600; color: var(--g100); }
.cert-s { font-size: 12.5px; color: var(--g60); margin-top: 3px; }
.cert-d {
  display: grid; gap: 12px 24px; margin: 16px 0 0;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}
.cert-f dt {
  font-size: 10.5px; font-weight: 600; letter-spacing: .06em;
  text-transform: uppercase; color: var(--g60);
}
.cert-f dd { margin: 4px 0 0; font-size: 13.5px; color: var(--g100); }
.cert-a { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 18px; }

/* --- the athlete dashboard: four panels, as the design arranges them --- */
.me-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; align-items: start; }
@media (max-width: 900px) { .me-cols { grid-template-columns: 1fr; } }

.pnl { display: flex; flex-direction: column; }
.pnl-h { display: flex; align-items: baseline; gap: 7px; padding: 14px 18px 0; }
.pnl-t { color: var(--saffron); font-weight: 600; font-size: 15px; }
.pnl-s { color: var(--g100); font-size: 15px; }
.pnl-a { margin-left: auto; font-size: 12.5px; color: var(--indigo); text-decoration: none; font-weight: 600; }
.pnl-a:hover { text-decoration: underline; }
.pnl-empty { color: var(--g70); font-size: 13px; line-height: 1.55; margin: 0; }

.pw-bar { height: 5px; background: var(--g20); border-radius: 3px; overflow: hidden; margin: 5px 0 3px; }
.pw-bar i { display: block; height: 100%; border-radius: 3px; }

/* A certificate drawn as a certificate. */
.certs { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
@media (max-width: 560px) { .certs { grid-template-columns: 1fr; } }
.cert-t { border: 1px solid var(--g20); background: #fff; }
.cert-p { position: relative; padding: 14px 12px 16px; text-align: center;
  background: linear-gradient(160deg, #fffaf4 0%, #fdf1e4 55%, #fbf7ee 100%);
  border-bottom: 3px solid var(--saffron); }
.cert-gov { font-size: 8px; letter-spacing: .12em; text-transform: uppercase; color: #9a7b53; }
.cert-k { font-size: 14px; font-weight: 700; color: #8a5a22; margin-top: 3px; }
.cert-n { font-size: 12px; color: var(--g100); margin-top: 6px; font-weight: 600; }
.cert-s { font-size: 10.5px; color: var(--g70); margin-top: 2px; }
.cert-seal { position: absolute; right: 9px; bottom: 7px; color: #d9a441; font-size: 15px; }
.cert-m { display: flex; align-items: center; gap: 8px; padding: 9px 11px; flex-wrap: wrap; }
.cert-l { font-size: 11.5px; color: var(--g100); flex: 1 1 auto; }

/* Notifications as a dated timeline. */
.tl { list-style: none; margin: 0; padding: 0 0 0 16px; border-left: 2px solid var(--g20); }
.tl-i { position: relative; padding: 0 0 14px 12px; }
.tl-i:last-child { padding-bottom: 0; }
.tl-i::before { content: ""; position: absolute; left: -21px; top: 4px; width: 8px; height: 8px;
  border-radius: 50%; background: var(--indigo); }
.tl-w { font-size: 11.5px; color: var(--g70); }
.tl-t { font-size: 13px; color: var(--g100); line-height: 1.5; margin-top: 2px; }

/* The campaign panel. */
.camp { position: relative; overflow: hidden; border: 1px solid var(--saffron-20);
  background: linear-gradient(135deg, var(--saffron-10) 0%, #fff 60%); min-height: 190px;
  display: flex; align-items: flex-end; }
/* Contained, not covered: the panel is a montage of athletes and a crop cuts
   people out of it -- see the rule beside .si-vip img. */
.camp-i { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain;
  object-position: center; }
.camp-b { position: relative; padding: 18px 20px; }
.camp-t { font-size: 26px; font-weight: 300; letter-spacing: .02em; color: var(--saffron);
  text-transform: uppercase; line-height: 1.1; }
.camp-s { font-size: 12.5px; color: var(--g100); margin-top: 6px; max-width: 34ch; }

/* The reason an official gave for a DNS, DNF or DQ, on the approval queue. */
.evt-note { margin-top: 9px; padding: 9px 12px; background: var(--saffron-10);
  border-left: 2px solid var(--saffron); font-size: 13px; line-height: 1.5; }

/* The event rail on capture and check-in.
   A venue running forty heats produced forty cards down the page, so the
   table beside them started below the fold. It scrolls in its own box now,
   and each card carries the full event name rather than the discipline
   alone -- "100 m" three times told nobody which heat they were looking at. */
.cap-rail { max-height: 560px; overflow-y: auto; }
.cap-ev-t { display: block; font-size: 13px; line-height: 1.35; }

/* The glyph on a figure card. Tinted to the card's own bar colour rather than
   to the text, so it reads as part of the figure and not as a control. */
.kpi-top { display: flex; align-items: flex-start; gap: 10px; }
.kpi-ico { flex: none; width: 34px; height: 34px; color: var(--indigo); opacity: .6; margin-top: -3px; }
.kpi.ok .kpi-ico { color: #24a148; }
.kpi.warn .kpi-ico { color: #b28600; }
.kpi.bad .kpi-ico { color: var(--red); }

/* --- the product's own confirm dialog ------------------------------------
   Replaces window.confirm, which titles itself with the server's IP address
   and cannot be translated. */
.dlg-back {
  position: fixed; inset: 0; z-index: 60;
  background: rgba(22, 22, 22, .45);
  display: flex; align-items: center; justify-content: center; padding: 20px;
}
.dlg {
  background: #fff; border-radius: 10px; width: min(440px, 100%);
  box-shadow: 0 18px 48px rgba(0, 0, 0, .22); overflow: hidden;
}
.dlg-h {
  padding: 13px 20px; font-size: 13.5px; font-weight: 600; color: var(--g100);
  background: var(--g10); border-bottom: 1px solid var(--g20);
}
.dlg-i { display: flex; justify-content: center; color: #24a148; padding: 26px 0 4px; }
.dlg-m {
  margin: 0; padding: 10px 28px 4px; text-align: center;
  font-size: 14px; line-height: 1.55; color: var(--g90);
}
.dlg-a {
  display: flex; gap: 10px; justify-content: center; padding: 20px 20px 24px;
}
@media (prefers-reduced-motion: no-preference) {
  .dlg { animation: dlg-in .14s ease-out; }
  @keyframes dlg-in { from { transform: translateY(6px); opacity: 0 } to { transform: none; opacity: 1 } }
}

/* Download actions in a table cell. They were underlined links separated by a
   dot; a download is an action and the design draws it as a button. */
.cell-acts { display: inline-flex; gap: 8px; flex-wrap: wrap; }
/* Side by side on a desktop, where a long description beside them would
   otherwise squeeze the pair into a stack. They still wrap on a phone. */
@media (min-width: 900px) { .cell-acts { flex-wrap: nowrap; } }
.b-dl {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 14px; border: 1px solid var(--saffron); border-radius: 6px;
  background: var(--saffron); color: #fff; font-size: 12px; font-weight: 600;
  text-decoration: none; white-space: nowrap;
}
.b-dl:hover { background: var(--saffron-d); border-color: var(--saffron-d); color: #fff; }

/* Row actions: an outlined button with its own icon, so Edit and Delete read
   as different weights of decision rather than as two words. */
.b-act {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 7px 13px; border-radius: 6px; font-size: 12.5px; font-weight: 600;
  background: #fff; text-decoration: none; cursor: pointer; line-height: 1;
  border: 1px solid var(--indigo); color: var(--indigo);
}
.b-act:hover { background: var(--indigo-10); }
.b-act.danger { border-color: var(--red); color: var(--red70); }
.b-act.danger:hover { background: #fff1f1; }

/* The sports rail on the assignment screen reuses the roles rail, so a button
   has to shed the browser's button chrome to sit in it. */
button.perm-r {
  width: 100%; background: none; border: 0; border-left: 3px solid transparent;
  font: inherit; text-align: left; cursor: pointer;
}
.scope-pane[hidden] { display: none; }

/* The permission grid in its dialog. Wider than a confirmation, and it scrolls
   inside itself rather than pushing the page: twenty-seven grants in the
   master-data module do not fit a phone. */
.dlg-wide { width: min(940px, 100%); max-height: 88vh; display: flex; flex-direction: column; }
.dlg-wide .perm-wrap { margin: 0; border: 0; border-top: 1px solid var(--g20); min-height: 0; overflow: auto; }
.dlg-h { display: flex; align-items: center; gap: 12px; }
.dlg-x {
  margin-left: auto; text-decoration: none; color: var(--g60);
  font-size: 20px; line-height: 1; padding: 0 4px;
}
.dlg-x:hover { color: var(--g100); }
.dlg-wide .perm-act { justify-content: flex-start; }

/* The grievance inbox's decisions: who takes it, and how it ended. Two small
   forms in the last column, stacked, each with its own default button. The
   details column wraps rather than stretching the table off the screen. */
.grv-d { min-width: 200px; max-width: 320px; white-space: normal; line-height: 1.45; }
.grv-res { margin-top: 6px; padding: 6px 9px; background: var(--g10);
  border-left: 2px solid #24a148; font-size: 12.5px; }
.grv-none { color: var(--g60); font-size: 12.5px; }
/* A reference is quoted down a helpline; it must not break across lines. */
.grv-nw { white-space: nowrap; }
.grv-acts { display: flex; flex-direction: column; gap: 8px; min-width: 240px; }
.grv-f { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; margin: 0; }
.grv-f select, .grv-f input { flex: 1 1 140px; min-width: 0; font: inherit; font-size: 12.5px;
  padding: 6px 8px; border: 1px solid var(--g30); border-radius: 4px; background: #fff; }
