/* shared.css: components used on several pages, after design.css (workstream D, round 4).
   - the lifecycle stepper (.stp), one component at three sizes: L (series header, 32px
     nodes), M (/tracking rows, exam pages, 14px), S (/exams cards, 8px dots). Same colours,
     track and current treatment at every size: done = brand with a tick, now = the only
     saturated (saffron) node with a "Now" tag, next = dashed ring, todo = hollow.
   - "Your exams" on the home page (#yourexams .yx), the Tracking dot (.has-upd), and the
     followed-exam rows on /tracking (.fl-row). follow.js draws these. */

/* ---------------------------------------------------------------- stepper */
.stp-box { container-type: inline-size; min-width: 0; }
/* sizes: .stp-l (large), .stp-m, .stp-s; a node's text is .stp-t */
.stp {
  --n: 32px; --tw: 3px; --gap: 12px;
  display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); margin: 0; padding: 0; list-style: none;
}
.stp > li { position: relative; min-width: 0; padding: calc(var(--n) + var(--gap)) 8px 0 0; }
/* the track from this node to the next */
.stp > li::before {
  content: ""; position: absolute; top: calc(var(--n) / 2 - var(--tw) / 2); left: calc(var(--n) + 4px); right: 4px;
  height: var(--tw); border-radius: var(--tw);
  background: repeating-linear-gradient(90deg, var(--rule-2) 0 6px, transparent 6px 11px);
}
.stp > li:last-child::before { display: none; }
.stp > li.st-done::before { background: var(--brand-fill); }
.stp i {
  position: absolute; top: 0; left: 0; box-sizing: border-box; display: grid; place-items: center;
  width: var(--n); height: var(--n); border-radius: 50%; background: var(--surface); border: 2px solid var(--rule-2);
}
.stp .st-done i { background: var(--brand-fill); border-color: var(--brand-fill); }
/* the tick, drawn with borders: no icon request, any size */
.stp .st-done i::after {
  content: ""; width: 26%; height: 46%; margin-top: -10%; border: solid var(--on-brand);
  border-width: 0 max(2px, calc(var(--n) / 12)) max(2px, calc(var(--n) / 12)) 0; transform: rotate(45deg);
}
.stp .st-now i { background: var(--live); border-color: var(--live); box-shadow: 0 0 0 calc(var(--n) / 6) rgb(var(--live-rgb) / .22); }
.stp .st-now i::before { content: ""; width: 32%; height: 32%; border-radius: 50%; background: var(--surface); }
/* the pulse: a ring that grows and fades three times, then stops (H2, MO F7) */
.stp .st-now i::after {
  content: ""; position: absolute; inset: -2px; border-radius: 50%; border: 2px solid var(--live); opacity: 0;
  animation: stp-pulse 1.8s cubic-bezier(.2, .6, .3, 1) .4s 3;
}
@keyframes stp-pulse {
  0% { transform: scale(1); opacity: .8; }
  100% { transform: scale(1.9); opacity: 0; }
}
.stp .st-next i { border-color: var(--rule-2); } /* Q19 (OD60): next looks like not-yet everywhere */
/* skip (OD14): a step this exam does not have, such as a bank's answer key: a hollow dashed
   node, its label muted, "not published" under it; never next, never done */
.stp .st-skip i { border-style: dashed; border-color: var(--ink-3); background: transparent; opacity: .75; }
.stp .st-skip .stp-t, .stp .st-skip .stp-d { color: var(--ink-3); font-weight: 500; }
.stp-t { display: block; font-size: .9375rem; font-weight: 600; line-height: 1.3; color: var(--ink-2); overflow-wrap: anywhere; }
.stp .st-done .stp-t, .stp .st-now .stp-t { color: var(--ink); }
.stp .st-now .stp-t { font-weight: 700; }
.stp-now {
  display: inline-block; margin: 4px 6px 0 0; padding: 1px 8px; border-radius: var(--r-pill);
  background: var(--live); color: #3d2600; font-size: .6875rem; font-style: normal; font-weight: 750;
  letter-spacing: .04em; text-transform: uppercase; line-height: 1.5; vertical-align: middle;
}
.stp-now:lang(hi) { letter-spacing: 0; text-transform: none; font-size: .75rem; }
.stp-d { display: inline-block; margin-top: 4px; font-size: .8125rem; color: var(--ink-2); font-variant-numeric: tabular-nums; vertical-align: middle; }
.stp .st-now .stp-d { color: var(--live-ink); font-weight: 650; }
.stp .is-seen .stp-d { color: var(--ink-3); font-weight: 500; font-style: normal; } /* Q20 (DS F5): roman, muted */
/* P23: Devanagari has no italic; the browser would slant it (QM S-360-light-hi) */
.stp .is-seen .stp-d:lang(hi), .stp .stp-d:lang(hi), .stp em:lang(hi) { font-style: normal; }

/* M: /tracking rows and exam pages */
.stp-m { --n: 14px; --tw: 2px; --gap: 8px; }
.stp-m .stp-t { font-size: .75rem; }
.stp-m .stp-d { font-size: .75rem; margin-top: 2px; }
.stp-m .stp-now { font-size: .6875rem; padding: 0 6px; margin-top: 2px; } /* ≥ 11px (M23) */
.stp-m .stp-now:lang(hi) { font-size: .75rem; }
/* M: the label and its "Now" share a line; the sub-line goes under them */
.stp-m .stp-t { display: inline; }
.stp-m .stp-now { margin: 0 0 0 6px; }
.stp-m .stp-d { display: block; }
.stp-m .st-now i::before { width: 40%; height: 40%; }
.stp-m .st-done i::after { border-width: 0 2px 2px 0; }

/* Q19 (OD60): the progress glyph, one shape at every small size (desktop strip, phone strip,
   /exams cards; the series and /tracking steppers use the same states and colours): done = a
   filled 6px dot and a 2px solid connector, now = an amber dot with a 3px halo, next and not
   yet = a 1.5px outlined dot and a dashed connector, skip = not yet, fainter. Each node is a dot
   (::before) and its connector to the next (::after), so the glyph stretches to any width and
   keeps its connectors with a 2px gap on each side. Static: the dots never pulse (J20). */
.pg { display: flex; align-items: center; width: 100%; height: 12px; padding-inline: 3px; box-sizing: border-box; }
.pg > i { display: flex; align-items: center; flex: 1 1 0; min-width: 0; }
.pg > i:last-child { flex: none; }
.pg > i::before { content: ""; flex: none; box-sizing: border-box; width: 6px; height: 6px; border-radius: 50%; border: 1.5px solid var(--ink-3); background: transparent; }
.pg > i:not(:last-child)::after {
  content: ""; flex: 1 1 auto; min-width: 3px; height: 2px; margin-inline: 2px; border-radius: 1px;
  background: repeating-linear-gradient(90deg, var(--rule-2) 0 3px, transparent 3px 5px);
}
.pg > .pg-d::before { border-color: var(--brand-fill); background: var(--brand-fill); }
.pg > .pg-d:not(:last-child)::after { background: var(--brand-fill); }
.pg > .pg-now::before { border-color: var(--live); background: var(--live); box-shadow: 0 0 0 3px rgb(var(--live-rgb) / .28); }
/* R9 (R29, DS zoom): one skip glyph at every size: the dot is the series stepper's dashed
   hollow node in small, in the same colour (st-skip below) */
.pg > .pg-skip::before { border-style: dashed; border-color: var(--ink-3); opacity: .75; }

/* narrow, or large text: the L and M steppers go vertical, labels beside the nodes
   (GOV.UK step-by-step). rem in a container query is the root size, so 200% text
   flips it at any width. */
@container (max-width: 34rem) {
  .stp:not(.stp-s) { grid-template-columns: minmax(0, 1fr); }
  .stp:not(.stp-s) > li { padding: 0 0 var(--gap) calc(var(--n) + 12px); min-height: calc(var(--n) + var(--gap)); }
  .stp:not(.stp-s) > li::before {
    top: calc(var(--n) + 3px); bottom: 3px; left: calc(var(--n) / 2 - var(--tw) / 2); right: auto; width: var(--tw); height: auto;
    background: repeating-linear-gradient(180deg, var(--rule-2) 0 5px, transparent 5px 9px);
  }
  .stp:not(.stp-s) > li.st-done::before { background: var(--brand-fill); }
  .stp:not(.stp-s) .stp-t { display: inline; margin-right: 8px; line-height: var(--n); }
  .stp:not(.stp-s) .stp-now, .stp:not(.stp-s) .stp-d { margin-top: 0; }
  .stp-m > li { padding-bottom: 6px; }
  .stp-m .stp-t { line-height: 1.35; }
  /* Q19 (DS F5): the NOW halo and its pulse stay inside the page gutter */
  .stp-l { margin-left: 6px; }
  .stp-l .st-now i::after { animation-name: stp-pulse-in; }
}
@keyframes stp-pulse-in {
  0% { transform: scale(1); opacity: .8; }
  100% { transform: scale(1.2); opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .stp .st-now i::after { animation: none; }
}
@media (forced-colors: active) {
  .stp i { forced-color-adjust: none; }
}

/* ---------------------------------------------------------------- Tracking dot */
.nav a.has-upd, .tabbar a.has-upd { position: relative; }
/* J19: 8px with a 2px surface ring; in light the darker saffron (#b45309, ≥ 3:1 on white,
   AX F4), in dark the bright one */
.has-upd::after {
  content: ""; position: absolute; width: 8px; height: 8px; border-radius: 50%; background: #b45309;
  box-shadow: 0 0 0 2px var(--surface); pointer-events: none;
}
:root[data-theme="dark"] .has-upd::after { background: var(--live); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .has-upd::after { background: var(--live); } }
.nav a.has-upd::after { top: 5px; right: 4px; }
.tabbar a.has-upd::after { top: 7px; left: calc(50% + 9px); }

/* ---------------------------------------------------------------- Your exams (home) */
/* J12 (K9): themeJS sets :root.yx-slot before first paint when this device follows an exam
   or has a profile, so the slot holds the strip's height from the start and the page does
   not shift when follow.js draws it. The strip's height is fixed per breakpoint (one row of
   equal chips), the skeleton has the same box, and follow.js drops the class when there is
   nothing to draw. */
:root { --yx-h: 116px; --yx-chip: 72px; }
.yx, :root.yx-slot #yourexams { box-sizing: border-box; height: var(--yx-h); margin-top: 12px; margin-bottom: 4px; overflow: hidden; }
:root.yx-slot #yourexams[hidden] { display: block !important; } /* beats the global [hidden] !important */
:root.yx-slot #yourexams[hidden]::before, :root.yx-slot #yourexams[hidden]::after { content: ""; display: block; }
/* the skeleton: a heading bar, then three chip blocks (static: no shimmer) */
:root.yx-slot #yourexams[hidden]::before { width: 8rem; height: 18px; margin: 5px 0 15px; border-radius: 6px; background: var(--raised); }
:root.yx-slot #yourexams[hidden]::after {
  height: var(--yx-chip); border-radius: var(--r);
  background:
    linear-gradient(var(--raised), var(--raised)) 0 0 / 240px 100% no-repeat,
    linear-gradient(var(--raised), var(--raised)) 248px 0 / 240px 100% no-repeat,
    linear-gradient(var(--raised), var(--raised)) 496px 0 / 240px 100% no-repeat;
}
.yx[hidden] { display: none; }
:root.yx-slot .yx[hidden] { display: block !important; }
.yx-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; height: 28px; margin-bottom: 8px; }
.yx-h { font-family: var(--display); font-size: 1.125rem; font-weight: 650; line-height: 28px; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.yx-h:focus { outline: none; }
.yx-h:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; border-radius: 4px; }
.yx-all { flex: none; font-size: .875rem; font-weight: 600; color: var(--brand); text-decoration: none; }
.yx-all:hover { text-decoration: underline; }
/* M23: a 44px target in the 28px head row (the padding overlaps, the row keeps its height) */
.yx-all { padding-block: 11px; margin-block: -11px; }
/* L9: "Done" ends the suggestions; it reads like the head's link */
.yx-done { border: 0; background: none; font: inherit; font-size: .875rem; font-weight: 600; color: var(--brand); cursor: pointer; padding-inline: 4px; margin-inline-end: -4px; }
.yx-done:focus-visible { outline: 2px solid var(--brand); outline-offset: -2px; border-radius: 6px; }
/* one row of equal chips: they share the row, and scroll sideways when they don't fit */
.yx-list {
  display: flex; gap: 8px; margin: 0 -16px; padding: 2px 16px 6px; list-style: none; overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory; scroll-padding-inline: 16px; scrollbar-width: none;
}
.yx-list::-webkit-scrollbar { display: none; }
.yx-li { flex: 1 0 240px; max-width: 360px; min-width: 0; scroll-snap-align: start; }
/* a chip: the name and the 5-dot stepper on one line, then two lines of what changed */
/* P10: one chip template, top-aligned: the name row (name + dots), then the meta line, so names
   share a baseline whatever the meta line's length */
.yx-chip {
  position: relative; display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-rows: auto auto; align-content: start;
  gap: 4px 10px; box-sizing: border-box;
  height: var(--yx-chip); padding: 6px 12px; border-radius: var(--r); text-decoration: none; color: var(--ink);
  background: var(--surface); border: 1px solid var(--rule); box-shadow: var(--shadow-1); transition: border-color .18s;
}
a.yx-chip:hover { border-color: var(--rule-2); color: var(--ink); }
a.yx-chip:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.yx-chip.is-upd { border-color: var(--live); }
.yx-top { grid-column: 1; grid-row: 1; display: flex; align-items: center; gap: 6px; min-width: 0; }
/* P23: chip names in Anek 16/650, like card titles */
.yx-n { min-width: 0; font-family: var(--display); font-weight: 650; font-size: 1rem; line-height: 1.25; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* the Updated dot sits beside the name (its word is for screen readers; the line says "New:") */
.yx-upd { flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--live); }
.yx-chip .stp-box { grid-column: 2; grid-row: 1; align-self: center; width: 5.5rem; min-width: 0; }
.yx-c {
  grid-column: 1 / -1; grid-row: 2; min-width: 0; font-size: .8125rem; line-height: 1.3; color: var(--ink-2);
  display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
/* fewer than four: the last cell offers another */
.yx-add {
  display: flex; align-items: center; justify-content: center; gap: 8px; box-sizing: border-box; height: var(--yx-chip); padding: 0 14px;
  border-radius: var(--r); border: 1.5px dashed var(--rule-2); color: var(--brand); font-size: .875rem; font-weight: 650; text-decoration: none; text-align: center;
}
.yx-add:hover { border-color: var(--brand); }
.yx-add:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.yx-plus { font-size: 1.25rem; line-height: 1; }
/* P1 (round 7): a refresh that failed. The strip keeps its chips (from the device).
   Q14 (round 8): the note "Couldn't refresh · showing 13 Oct, 15:21" is its own 13px line under
   the heading, the time never cut; the heading never ellipsises and "All on Tracking →" keeps
   its right slot. The strip keeps its height (--yx-h): its chips give the note one meta line
   (the strip is drawn afresh in this state, so nothing on the page moves). On home the note has
   no button: the banner's Retry refreshes both (M5). */
.fl-note { flex: 1 0 100%; order: 3; display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 8px; min-width: 0; margin: 0; font-size: .8125rem; line-height: 1.3; color: var(--ink-3); }
.fl-note-t { min-width: 0; white-space: normal; }
.fl-note-w { white-space: nowrap; }
.fl-retry {
  flex: none; border: 0; background: none; font: inherit; font-weight: 650; color: var(--brand); cursor: pointer;
  text-decoration: underline; text-underline-offset: 2px; padding: 11px 4px; margin: -11px -4px;
}
.fl-retry:focus-visible { outline: 2px solid var(--brand); outline-offset: -8px; border-radius: 6px; }
.yx-head.is-stale { flex-wrap: wrap; height: auto; row-gap: 0; margin-bottom: 4px; }
.yx-head.is-stale .yx-h { flex: 0 0 auto; }
.yx.is-stale .yx-chip { height: calc(var(--yx-chip) - 13px); }
.yx.is-stale .yx-c, .yx.is-stale .yx-chip.is-long .yx-c { -webkit-line-clamp: 1; line-clamp: 1; }
.yx.is-stale .yx-chip.is-long .yx-n { -webkit-line-clamp: 1; line-clamp: 1; }
.yx.is-stale .yx-add { height: calc(var(--yx-chip) - 13px); }
/* /tracking: under the heading on phones; on its line from 720px, where it fits uncut (its
   section is drawn afresh, and nothing below it is in a phone's first screen) */
.fl-hrow { display: flex; flex-wrap: wrap; align-items: baseline; column-gap: 12px; min-width: 0; }
.fl-hrow .h-sec { flex: none; }
.fl-hrow .h-sec:focus { outline: none; }
.fl-hrow .h-sec:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; border-radius: 4px; }
.fl-tnote { margin-top: -4px; margin-bottom: 8px; }
@media (min-width: 720px) {
  .fl-hrow { flex-wrap: nowrap; }
  .fl-tnote { flex: 0 1 auto; order: 0; margin: 0 0 0 auto; }
}
/* Q14 (UF F2): one follow on a phone is no scroller: the chip and a 56px "+" square named
   "Follow an exam" */
@media (max-width: 599px) {
  .yx-list.n1 { overflow: visible; margin: 0; padding: 2px 0 6px; }
  .yx-list.n1 .yx-li { flex: 1 1 auto; max-width: none; }
  .yx-list.n1 .yx-addli { flex: 0 0 56px; }
  .yx-list.n1 .yx-add { padding: 0; }
  .yx-list.n1 .yx-add-t { display: none; } /* the link's aria-label names it */
}
/* L13 (P24): /me lists the followed exams, linked, with the stage word when known */
.me-fol { display: flex; flex-wrap: wrap; gap: 8px; margin: 10px 0 6px; padding: 0; list-style: none; }
.me-fol-a {
  display: inline-flex; align-items: baseline; gap: 6px; min-height: 36px; box-sizing: border-box; padding: 8px 12px; border-radius: var(--r-pill);
  border: 1px solid var(--rule); background: var(--surface); color: var(--ink); font-size: .875rem; font-weight: 650; line-height: 1.3; text-decoration: none;
}
.me-fol-a:hover { border-color: var(--brand); }
.me-fol-a:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.me-fol-st { font-weight: 500; font-size: .8125rem; color: var(--ink-2); }
/* M18: a name too long for its line wraps to two (never "…"), and the dots go under it */
.yx-chip.is-long { grid-template-columns: auto minmax(0, 1fr); row-gap: 2px; }
.yx-chip.is-long .yx-top { grid-column: 1 / -1; }
.yx-chip.is-long .yx-n { white-space: normal; text-overflow: clip; line-height: 1.2; display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; overflow-wrap: anywhere; }
.yx-chip.is-long .stp-box { grid-column: 1; grid-row: 2; width: 4.25rem; }
.yx-chip.is-long .yx-c { grid-column: 2; grid-row: 2; -webkit-line-clamp: 1; line-clamp: 1; }
.yx-sg.is-long { grid-template-columns: minmax(0, 1fr) auto; }
.yx-sg.is-long .yx-n { grid-column: 1; }
.yx-sg.is-long .yx-c { grid-column: 1; }
/* suggestions (a profile, no follows): name and stage beside a Follow button */
.yx-sg { grid-template-columns: minmax(0, 1fr) auto; grid-template-rows: auto auto; column-gap: 10px; }
.yx-sg .yx-n { grid-column: 1; grid-row: 1; }
.yx-sg .yx-c { grid-column: 1; grid-row: 2; }
.yx-sg .yx-n a { color: inherit; text-decoration: none; }
.yx-sg .yx-n a::after { content: ""; position: absolute; inset: 0; border-radius: inherit; }
.yx-sg .yx-n a:focus-visible { outline: none; }
.yx-sg .yx-n a:focus-visible::after { outline: 2px solid var(--brand); outline-offset: 2px; }
.yx-fb {
  grid-column: 2; grid-row: 1 / span 2; align-self: center; position: relative; z-index: 1; display: inline-flex; align-items: center; gap: 6px;
  min-height: 44px; padding: 0 14px; border-radius: var(--r-pill); border: 1px solid var(--brand); background: var(--brand); color: var(--on-brand);
  font: inherit; font-size: .8125rem; font-weight: 650; cursor: pointer; white-space: nowrap;
}
.yx-fb .ico { width: 16px; height: 16px; }
.yx-fb.is-on { background: var(--surface); color: var(--brand); }

/* the stage pill, coloured by stage (/tracking rows) */
.stg { display: inline-block; padding: 1px 8px; border-radius: var(--r-pill); font-size: .75rem; font-weight: 650; line-height: 1.5; background: var(--raised); color: var(--ink-2); }
.stg-notification { background: var(--brand-tint); color: var(--brand); }
.stg-exam_date, .stg-admit_card { background: var(--live-tint); color: var(--live-ink); }
.stg-answer_key { background: color-mix(in srgb, var(--brand) 12%, transparent); color: var(--brand); }
.stg-result { background: var(--brand-fill); color: var(--on-brand); }
.stg-none, .stg-unclear, .stg-varies { background: var(--raised); color: var(--ink-2); }

/* M18: the strip is as wide as the search box above it (DS F2: it ran 23px past the hero
   column). 600–1023px: two chips to a view; from 1024px a grid of three, never clipped, the
   full width of the hero column (P10: the search's right edge) */
.yourexams { max-width: 600px; }
@media (min-width: 600px) {
  .yx-list { margin: 0; padding: 2px 2px 6px; }
  .yx-li { flex: 0 0 calc((100% - 8px) / 2); max-width: none; }
}
@media (min-width: 1024px) {
  .yourexams { max-width: none; }
  .yx:not(.yx-sug) .yx-list { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; padding: 2px 0 6px; overflow: visible; }
  .yx:not(.yx-sug) .yx-chip { padding-inline: 10px; column-gap: 8px; }
  .yx:not(.yx-sug) .yx-chip .stp-box { width: 4.25rem; } /* Q19: room for the connectors */
  .yx:not(.yx-sug) .yx-4, .yx:not(.yx-sug) .yx-list.n3 .yx-addli { display: none; }
  /* P10 (PR N5): suggestions are a grid of three columns and two rows of slim chips (name
     and stage beside a small Follow), every one visible, in the strip's height:
     28 + 8 (head) + 36 + 8 + 36 = 116px */
  .yx-sug .yx-list { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); grid-auto-rows: 36px; gap: 8px; margin: 0; padding: 0; overflow: visible; }
  .yx-sug .yx-li { max-width: none; }
  .yx-sug .yx-chip, .yx-sug .yx-chip.is-long { height: 36px; padding: 0 3px 0 10px; grid-template-columns: minmax(0, 1fr) auto; align-content: center; row-gap: 0; column-gap: 6px; }
  .yx-sug .yx-n, .yx-sug .yx-chip.is-long .yx-n { display: flex; align-items: center; gap: 6px; font-size: .875rem; line-height: 1.2; white-space: nowrap; -webkit-line-clamp: unset; line-clamp: none; }
  .yx-sug .yx-n a { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
  .yx-sug .yx-c, .yx-sug .yx-chip.is-long .yx-c { font-size: .75rem; line-height: 1.2; white-space: nowrap; display: block; text-overflow: ellipsis; }
  .yx-sug .yx-fb { min-height: 30px; height: 30px; padding: 0 10px; gap: 4px; font-size: .75rem; }
  .yx-sug .yx-fb .ico { width: 14px; height: 14px; }
  /* followed: the tick says it (the button's name says "Following …") */
  .yx-sug .yx-fb.is-on { padding: 0 8px; }
  .yx-sug .yx-fb.is-on .yx-fl { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  /* the skeleton: three equal blocks, as the grid draws them */
  :root.yx-slot #yourexams[hidden]::after {
    background:
      linear-gradient(var(--raised), var(--raised)) 0 0 / calc((100% - 16px) / 3) 100% no-repeat,
      linear-gradient(var(--raised), var(--raised)) 50% 0 / calc((100% - 16px) / 3) 100% no-repeat,
      linear-gradient(var(--raised), var(--raised)) 100% 0 / calc((100% - 16px) / 3) 100% no-repeat;
  }
}

/* ---------------------------------------------------------------- /tracking rows */
.fl-row.jr { grid-template-columns: minmax(0, 1fr); }
.fl-row .jr-main { display: grid; gap: 6px; min-width: 0; }
.fl-row .jr-eye { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; }
.fl-head { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px; min-width: 0; }
.fl-head .jr-title { margin: 0; }
.fl-head .fl-fb { margin-inline-start: auto; }
.fl-head .fl-latest { flex: 1 1 100%; order: 3; }
@media (min-width: 720px) {
  /* M23: name, latest notice and Follow on one line; the stepper below has the row's width */
  .fl-head { flex-wrap: nowrap; }
  .fl-head .jr-title { flex: none; max-width: 40%; }
  .fl-head .fl-latest { flex: 1 1 auto; order: 0; flex-wrap: nowrap; }
  .fl-head .fl-latest a { flex: 1 1 auto; }
}
.fl-latest { display: flex; gap: 2px 8px; flex-wrap: wrap; align-items: baseline; font-size: .875rem; color: var(--ink-2); min-width: 0; }
.fl-k { flex: none; font-size: .75rem; font-weight: 650; color: var(--ink-3); letter-spacing: .02em; }
.fl-latest a { flex: 1 1 12rem; min-width: 0; color: var(--ink); display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
@media (min-width: 720px) { .fl-latest a { -webkit-line-clamp: 1; line-clamp: 1; } }
/* J19: horizontal from 720px (the container query in the stepper flips it below 34rem, and at
   200% text) */
.fl-row .stp-box { margin-top: 2px; }
/* the current node's sub-line is the row's news: its column is wider, so "rescheduled ·
   notice 5 Oct" keeps one line (M23); browsers without :has() keep five equal columns */
@container (min-width: 34.01rem) {
  .fl-row .stp-m:has(> li:nth-child(1).st-now) { grid-template-columns: 1.8fr 1fr 1fr 1fr 1fr; }
  .fl-row .stp-m:has(> li:nth-child(2).st-now) { grid-template-columns: 1fr 1.8fr 1fr 1fr 1fr; }
  .fl-row .stp-m:has(> li:nth-child(3).st-now) { grid-template-columns: 1fr 1fr 1.8fr 1fr 1fr; }
  .fl-row .stp-m:has(> li:nth-child(4).st-now) { grid-template-columns: 1fr 1fr 1fr 1.8fr 1fr; }
  .fl-row .stp-m:has(> li:nth-child(5).st-now) { grid-template-columns: 1fr 1fr 1fr 1fr 1.8fr; }
}
.fl-skel { display: grid; gap: 10px; padding: 16px; }
.fl-skel i { display: block; height: 12px; border-radius: 6px; background: var(--raised); }
.fl-skel i:nth-child(1) { width: 40%; height: 16px; }
.fl-skel i:nth-child(2) { width: 75%; }
.fl-skel i:nth-child(3) { width: 90%; height: 18px; }
@media (prefers-reduced-motion: no-preference) {
  .fl-skel i { animation: fl-shim 1.2s ease-in-out infinite alternate; }
  @keyframes fl-shim { to { opacity: .55; } }
}
.fl-fb {
  align-self: start; display: inline-flex; align-items: center; gap: 6px; min-height: 44px; padding: 0 12px; border-radius: var(--r-pill);
  border: 1px solid var(--brand); background: var(--brand); color: var(--on-brand); font: inherit; font-size: .8125rem; font-weight: 650; cursor: pointer; white-space: nowrap;
  /* P17: above the row's stretched title link (it covered the button: a tap opened the exam) */
  position: relative; z-index: 1;
}
.fl-fb .ico { width: 16px; height: 16px; }
.fl-fb.is-on { background: var(--surface); color: var(--brand); }
.fl-fb:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.fl-row.is-off { opacity: .62; }
.fl-skel-box { padding: 0; }
.fl-legend { margin-top: 10px; font-size: .8125rem; line-height: 1.5; color: var(--ink-3); }
/* M23: breadcrumb links are 44px targets; the padding overlaps, the line keeps its height */
.crumbs a { padding-block: 11px; margin-block: -11px; }
@media (max-width: 599px) {
  .fl-fb .fl-fl { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .fl-fb { padding: 0; width: 44px; justify-content: center; }
}

/* placeholders: the browser grey is 3.5:1 on the dark surface */
::placeholder { color: var(--ink-3); opacity: 1; }

/* A calm, consistent account surface. Preference controls preserve their native state. */
.p-me .page-head { background: linear-gradient(120deg,var(--hero-bg),var(--page)); padding-block: 32px; }
.p-me .page-head .read, .p-me .me { max-width: 1000px; }
.p-me .me { grid-template-columns: repeat(2,minmax(0,1fr)); gap: 16px; padding-block: 28px 48px; }
.p-me .me .panel { padding: 28px; border: 1px solid var(--rule); box-shadow: none; border-radius: 16px; }
.p-me .me .h-panel { display: flex; align-items: center; gap: 10px; font-size: 1.125rem; }
.p-me .me .h-panel .ico { width: 20px; height: 20px; color: var(--brand); }
.p-me .me-eligibility, .p-me .me-tracking { display: flex; flex-direction: column; align-items: flex-start; }
.p-me .me .panel-link { display: inline-flex; align-items: center; min-height: 44px; margin-top: auto; padding-block: 8px; }
.p-me .me-eligibility .panel-link { padding-inline: 16px; background: var(--brand); color: var(--on-brand); border-radius: 8px; text-decoration: none; }
.p-me .me-preference, .p-me .me-resources { grid-column: 1 / -1; }
.p-me .me-preference { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.p-me .me-preference .h-panel { margin: 0; }
.p-me .choice { border: 1px solid var(--rule); border-radius: 10px; }
.p-me .choice a, .p-me .choice label { min-height: 44px; padding-inline: 18px; }
.p-me .me-resources .link-list { display: flex; flex-wrap: wrap; gap: 12px 28px; }
.p-me .me-resources .link-list li { border: 0; }
@media (max-width:599px) {
 .p-me .page-head { padding-block: 24px; }
 .p-me .me { grid-template-columns: minmax(0,1fr); gap: 12px; padding-top: 20px; }
 .p-me .me .panel { padding: 20px; }
 .p-me .me-preference { flex-direction: column; align-items: stretch; gap: 12px; }
 .p-me .choice { display: flex; }
 .p-me .choice a, .p-me .choice label { flex: 1; text-align: center; padding-inline: 8px; }
 .p-me .me-resources .link-list { display: block; }
}
