/* Cybersecurity Awareness course
   Look: a printed safety manual. Serif headings, stencil-style mono tags,
   signage colours used only where they carry meaning. No web fonts, so the
   page renders identically offline and from file://. */

/* Three themes, selectable from the header and remembered per browser.
   The base :root is the default "printed safety manual" look; the two
   [data-theme] blocks below only override the colour tokens, so every
   component inherits the right palette automatically. Each palette is
   tuned so body and muted text stay well above WCAG AA contrast on its
   own surfaces — legibility first, in every theme. */
:root {
  --concrete:   #F3F2EE;
  --card:       #FFFFFF;
  --ink:        #17181C;
  --slate:      #5A5E68;
  --hairline:   #DAD8D1;
  --signal:     #B3261E;   /* incorrect / caution */
  --verify:     #1F7A4D;   /* correct / cleared */
  --tape:       #E0A500;   /* the signature accent */
  /* --tape itself is a border/background accent, not tuned for text - used
     as text color directly (the certificate's rank label and date stamp)
     it measures only ~1.7:1 against --concrete, well under the 3:1/4.5:1
     WCAG floor. This darker variant is for exactly those direct-text
     uses; --tape itself (borders, hover backgrounds, the rank-up toast)
     is unchanged. */
  --tape-text:  #6B4A00;
  --halo:       rgba(23, 24, 28, .55);   /* behind the level-up text - see .levelup below */
  /* the refresh (2026-10-20): soft surfaces, the "correct" and "careful" washes, shape and depth */
  --soft:       #E8E7E1;
  --row:        #ECEAE4;
  --ok-bg:      #E4F3EA;
  --warn-bg:    #FFF4D6;
  --warn-text:  #4A3500;
  --radius:     12px;
  --radius-sm:  8px;
  --shadow:     0 1px 2px rgba(23, 24, 28, .06), 0 2px 8px rgba(23, 24, 28, .05);
  color-scheme: light;

  --serif: "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, "Times New Roman", serif;
  --sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", "Cascadia Mono", Menlo, Consolas, monospace;

  --gap: 1.5rem;
  --edge: clamp(1rem, 4vw, 2.5rem);
  --measure: 68ch;
}

/* Light — crisper and whiter than the warm default, with near-black text
   and a darker muted grey for stronger secondary-text contrast. */
:root[data-theme="light"] {
  --concrete:   #FFFFFF;
  --card:       #F6F6F4;
  --ink:        #0F1013;
  --slate:      #4A4E58;
  --hairline:   #D6D6D0;
  --signal:     #A8201A;
  --verify:     #176A42;
  --soft:       #ECECE8;
  --row:        #F0F0EC;
  --ok-bg:      #E4F3EA;
  --warn-bg:    #FFF4D6;
  --warn-text:  #4A3500;
  --tape:       #A97600;
  --tape-text:  #A97600;   /* same as --tape - preserves this theme's existing certificate appearance unchanged; only the default theme's value was flagged and changed */
  --halo:       rgba(10, 12, 11, .5);
  color-scheme: light;
}

/* Dark — light text on a deep neutral. The signage colours are brightened
   so correct/incorrect/accent stay legible against the dark surfaces. */
:root[data-theme="dark"] {
  --concrete:   #15161A;
  --card:       #1E2025;
  --ink:        #F1F0EC;
  --slate:      #A3A7B0;
  --hairline:   #33363D;
  --signal:     #FF8A80;
  --verify:     #5CC98F;
  --soft:       #2A2D34;
  --row:        #2A2D34;
  --ok-bg:      #1C3A2B;
  --warn-bg:    #3A2E10;
  --warn-text:  #F2D98A;
  --shadow:     0 1px 2px rgba(0, 0, 0, .4), 0 2px 8px rgba(0, 0, 0, .3);
  --tape:       #F0B429;
  --tape-text:  #F0B429;   /* same as --tape - preserves this theme's existing certificate appearance unchanged; only the default theme's value was flagged and changed */
  --halo:       rgba(238, 241, 240, .45);   /* light glow, not a dark outline - a dark halo would vanish into this ground */
  color-scheme: dark;
}

* { box-sizing: border-box; margin: 0; padding: 0; }

html { -webkit-text-size-adjust: 100%; }

body {
  background: var(--concrete);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 1rem;
  line-height: 1.6;
}

body.is-locked { overflow: hidden; }

:focus-visible {
  outline: 3px solid var(--ink);
  outline-offset: 2px;
}

.skip {
  position: absolute;
  left: -999px;
}

/* Visually hidden but still reachable by assistive tech - unlike
   `hidden`/`display:none`, an aria-live region has to stay in the
   accessibility tree to ever be announced. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
.skip:focus {
  left: 1rem;
  top: 1rem;
  z-index: 200;
  background: var(--ink);
  color: var(--card);
  padding: .6rem 1rem;
  border-radius: 2px;
}

/* ---------- shared bits ---------- */

.tag {
  font-family: var(--mono);
  font-size: .6875rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--slate);
}

.btn {
  display: inline-block;
  font-family: var(--sans);
  font-size: .875rem;
  font-weight: 600;
  line-height: 1;
  padding: .9rem 1.1rem; /* was .7rem - computed to ~38px tall, under the ~44px touch-target guideline */
  border: 1px solid var(--ink);
  border-radius: 2px;
  background: transparent;
  color: var(--ink);
  cursor: pointer;
  transition: background .15s ease, color .15s ease;
}
/* The browser's own [hidden] { display: none } rule and this file's own
   `.btn { display: inline-block }` above are the SAME specificity (one
   attribute selector, one class selector) - and an author stylesheet beats
   the user-agent stylesheet on a tie, not the other way around. Without
   this, setting `.hidden = true` on any <a class="btn"> or <button
   class="btn"> left it fully visible and clickable regardless - the JS
   property read true, but nothing on screen reflected it. This selector is
   more specific than plain `.btn` (element/class + attribute), so it wins
   outright rather than relying on cascade order. */
.btn[hidden] { display: none; }
.btn:hover:not(:disabled) { background: var(--ink); color: var(--card); }
.btn:disabled { opacity: .35; cursor: not-allowed; }

.btn--primary { background: var(--ink); color: var(--card); }
.btn--primary:hover:not(:disabled) { background: var(--verify); border-color: var(--verify); }

.btn--quiet { border-color: var(--hairline); color: var(--slate); font-weight: 500; }

/* The link to the page you are already on: visibly "here", not a button. */
.btn.is-current,
.btn.is-current:hover {
  background: transparent;
  color: var(--slate);
  border-color: var(--hairline);
  opacity: .6;
  cursor: default;
  pointer-events: none;
}

/* ---------- top bar ---------- */

.bar {
  background: var(--card);
  border-bottom: 1px solid var(--hairline);
}

.bar__inner {
  max-width: 1100px;
  margin: 0 auto;
  padding: 1rem var(--edge);
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  align-items: center;
  justify-content: space-between;
}

.bar__brand { display: flex; gap: 1rem; align-items: stretch; }

/* The RuleCrest brand mark. align-self: center overrides the parent's
   align-items: stretch, which would otherwise force the image to fill the
   row's cross-axis height and distort its proportions - only an explicit
   height (set per variant below) controls the size, width stays auto so
   the aspect ratio is never deformed. */
.brand-logo {
  display: block;
  width: auto;
  align-self: center;
}
/* The compact square shield mark - login/admin utility pages. */
.brand-logo--icon { height: 2.375rem; }
/* The wide wordmark lockup - the training experience and the certificate. */
.brand-logo--full { height: 2.75rem; }

.bar__title {
  font-family: var(--serif);
  font-size: 1.375rem;
  font-weight: 600;
  letter-spacing: -.01em;
  line-height: 1.2;
}

.bar__sub {
  font-family: var(--mono);
  font-size: .75rem;
  color: var(--slate);
  margin-top: .15rem;
}

.bar__tools { display: flex; gap: .75rem; align-items: flex-end; flex-wrap: wrap; }

.field { display: flex; flex-direction: column; gap: .25rem; }
/* Same same-specificity conflict as the .btn[hidden] comment above - this
   time for the Role/Theme selectors hidden on the multi-course picker. */
.field[hidden] { display: none; }
.field__label {
  font-family: var(--mono);
  font-size: .6875rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--slate);
}
.field select {
  font-family: var(--sans);
  font-size: .875rem;
  padding: .6rem .7rem;
  border: 1px solid var(--ink);
  border-radius: 2px;
  background: var(--card);
  color: var(--ink);
}

/* ---------- progress strip ---------- */

.track {
  background: var(--card);
  border-bottom: 1px solid var(--hairline);
  position: sticky;
  top: 0;
  z-index: 20;
}

.track__inner {
  max-width: 1100px;
  margin: 0 auto;
  padding: .85rem var(--edge) 1rem;
}

.track__meta {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  margin-bottom: .5rem;
}

.track__label { display: flex; align-items: baseline; gap: .5rem; min-width: 0; }

.track__module-name {
  font-family: var(--mono);
  font-size: .75rem;
  color: var(--slate);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.track__tally { font-family: var(--mono); font-size: .75rem; color: var(--slate); flex-shrink: 0; }

.meter {
  height: 3px;
  background: var(--hairline);
  border-radius: 2px;
  overflow: hidden;
  margin-bottom: .75rem;
}
.meter__fill {
  display: block;
  height: 100%;
  width: 0;
  background: var(--verify);
  transition: width .35s ease;
}

/* One cell per module: progress meter and navigation in a single control. */
.strip {
  display: grid;
  grid-template-columns: repeat(20, minmax(0, 1fr));
  gap: 3px;
}

.cell {
  position: relative;
  height: 44px; /* WCAG 2.5.5 target-size guidance - was a fixed 30px, too easy to mis-tap on mobile */
  border: 1px solid var(--hairline);
  border-radius: 2px;
  background: transparent;
  color: var(--slate);
  font-family: var(--mono);
  font-size: .625rem;
  cursor: pointer;
  display: grid;
  place-items: center;
  padding: 0;
  transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.cell:hover { border-color: var(--ink); color: var(--ink); }

.cell.is-attempted {
  border-color: var(--signal);
  color: var(--signal);
  background: rgba(194, 65, 12, .07);
}
.cell.is-cleared {
  background: var(--verify);
  border-color: var(--verify);
  color: var(--card);
}
.cell.is-current {
  border-color: var(--ink);
  border-width: 2px;
  color: var(--ink);
  font-weight: 700;
}
.cell.is-current.is-cleared { color: var(--card); }

.cell.is-locked { opacity: .4; cursor: not-allowed; }

.cell__num { pointer-events: none; }

/* ---------- module page ---------- */

main {
  max-width: 1100px;
  margin: 0 auto;
  padding: clamp(1.5rem, 5vw, 3rem) var(--edge) 4rem;
}

.module { outline: none; }

.module__eyebrow {
  display: flex;
  gap: .5rem;
  align-items: baseline;
  margin-bottom: .4rem;
}
.module__of { font-family: var(--mono); font-size: .6875rem; color: var(--slate); }

.module__title {
  font-family: var(--serif);
  font-size: clamp(1.75rem, 4.5vw, 2.75rem);
  font-weight: 600;
  line-height: 1.12;
  letter-spacing: -.02em;
  max-width: 22ch;
  margin-bottom: 1.5rem;
}

.tip {
  border-left: 3px solid var(--tape);
  background: var(--card);
  padding: .9rem 1.1rem;
  border-radius: 0 2px 2px 0;
  margin-bottom: 1.25rem;
  max-width: var(--measure);
}
.tip__label {
  display: block;
  font-family: var(--mono);
  font-size: .6875rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--slate);
  margin-bottom: .25rem;
}
.tip__body { font-size: .9375rem; }

.principle {
  font-family: var(--serif);
  font-size: 1.125rem;
  font-style: italic;
  line-height: 1.5;
  color: var(--ink);
  padding-left: 1.1rem;
  border-left: 1px solid var(--hairline);
  margin-bottom: 1rem;
  max-width: var(--measure);
}

.module__body {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
  gap: var(--gap);
  margin: 2rem 0;
}

.panel {
  background: var(--card);
  border: 1px solid var(--hairline);
  border-radius: 2px;
  padding: 1.25rem;
}
.panel--action { border-top: 3px solid var(--tape); }

.panel__head {
  font-family: var(--mono);
  font-size: .6875rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--slate);
  font-weight: 500;
  margin-bottom: .85rem;
}

.panel__list { list-style: none; display: flex; flex-direction: column; gap: .7rem; }
.panel__list li {
  font-size: .9375rem;
  line-height: 1.55;
  padding-left: 1.1rem;
  position: relative;
}
.panel__list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: .6em;
  width: 5px;
  height: 5px;
  background: var(--ink);
}
.panel--action .panel__list li::before { background: var(--tape); }

/* A learner who reads "What to know"/"Do this" and stops scrolling had no
   on-screen sign there was a video (and, behind it, the quiz) still below -
   a small, gently-nudging label closes that gap without restructuring the
   page. A real link (see app.js), so it needs its own underline reset -
   nothing in this stylesheet resets anchor styling globally. */
.scroll-cue {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .4rem;
  font-family: var(--mono);
  font-size: .75rem;
  letter-spacing: .04em;
  color: var(--slate);
  text-decoration: none;
  margin: -1rem 0 1.25rem;
  animation: scroll-cue-nudge 1.6s ease-in-out infinite;
}
@keyframes scroll-cue-nudge {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(4px); }
}

/* ---------- lesson (src/app.js renderLesson) ----------
   One short step at a time. Uses the page's own tokens: serif for the key sentence, mono for labels, tape yellow for the
   position marker, --verify for what has been read. Motion is one short slide-in per step, off for reduced motion. */
.lesson { margin: 2rem 0; max-width: 100%; scroll-margin-top: 9rem; }
.quiz-area { scroll-margin-top: 9rem; }
/* Offscreen copy used to measure the tallest step (src/app.js measureSizing). */
.lesson__probe { position: absolute; left: 0; top: 0; visibility: hidden; pointer-events: none; }
.lesson__probe .lesson__card { animation: none; width: 100%; margin: 0; }

.lesson__top {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .5rem .75rem;
  margin-bottom: .75rem;
}
.lesson__length { font-family: var(--mono); font-size: .6875rem; color: var(--slate); }
.lesson__toggle {
  margin-left: auto;
  min-height: 44px;
  padding: 0 .25rem;
  border: 0;
  background: none;
  color: var(--slate);
  font: inherit;
  font-size: .875rem;
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}
.lesson__toggle:hover { color: var(--ink); }

/* The trail: one segment per screen, a button once reached. The hit area is 44px tall, the bar itself 6px. */
.lesson__trail { list-style: none; display: flex; gap: 4px; }
.lesson__seg { flex: 1 1 0; min-width: 0; }
.lesson__seg-btn {
  position: relative;
  display: block;
  width: 100%;
  min-height: 44px;
  border: 0;
  background: none;
  cursor: pointer;
}
.lesson__seg-btn:disabled { cursor: default; }
.lesson__seg-btn::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: 6px;
  margin-top: -3px;
  border-radius: 3px;
  background: var(--hairline);
  transition: background-color .2s ease;
}
.lesson__seg.is-done .lesson__seg-btn::before { background: var(--verify); }
.lesson__seg.is-current .lesson__seg-btn::before { background: var(--tape); height: 10px; margin-top: -5px; }

.lesson__meter {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-family: var(--mono);
  font-size: .75rem;
  letter-spacing: .02em;
  color: var(--slate);
  margin: .1rem 0 .6rem;
}

.lesson__card {
  position: relative;
  background: var(--card);
  border: 1px solid var(--hairline);
  border-top: 3px solid var(--tape);
  border-radius: 2px;
  padding: clamp(1.1rem, 3vw, 1.75rem);
  padding-right: clamp(3.2rem, 9vw, 4.5rem);
  animation: lesson-in .25s ease-out;
}
.lesson__card--do { border-top-color: var(--verify); }
@keyframes lesson-in {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: none; }
}
.lesson__kicker {
  font-family: var(--mono);
  font-size: .6875rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--slate);
  font-weight: 500;
  margin-bottom: .8rem;
  outline: none;
}
.lesson__kicker:focus-visible { outline: 3px solid var(--ink); outline-offset: 4px; }
.lesson__num {
  position: absolute;
  top: .55rem;
  right: .9rem;
  font-family: var(--serif);
  font-size: clamp(2.25rem, 7vw, 3.25rem);
  line-height: 1;
  font-weight: 600;
  color: var(--hairline);
  user-select: none;
  pointer-events: none;
}

.lesson__items { display: flex; flex-direction: column; gap: 1.25rem; }
.lesson__lead {
  font-family: var(--serif);
  font-size: clamp(1.25rem, 3.2vw, 1.5rem);
  line-height: 1.3;
  font-weight: 700;
  letter-spacing: -.01em;
  margin-bottom: .5rem;
}
.lesson__body { font-size: 1.0625rem; line-height: 1.65; }
.lesson__intro { color: var(--slate); font-size: .9375rem; margin-bottom: .9rem; }

.lesson__terms { list-style: none; display: flex; flex-wrap: wrap; gap: .4rem; margin-top: 1.25rem; }
.lesson__term {
  font-family: var(--mono);
  font-size: .75rem;
  letter-spacing: .04em;
  padding: .2rem .55rem;
  border: 1px solid var(--ink);
  border-radius: 2px;
  background: var(--concrete);
}

.lesson__actions { list-style: none; display: flex; flex-direction: column; gap: .7rem; }
.lesson__action {
  position: relative;
  padding: .85rem 1rem .85rem 2.6rem;
  background: var(--concrete);
  border: 1px solid var(--hairline);
  border-radius: 2px;
  font-size: 1.0625rem;
  line-height: 1.55;
}
.lesson__action::before {
  content: "";
  position: absolute;
  left: 1rem;
  top: 1.2rem;
  width: 11px;
  height: 11px;
  background: var(--verify);
  border-radius: 2px;
}

.lesson__nav { display: flex; justify-content: space-between; gap: .75rem; margin-top: 1rem; }
.lesson__nav .btn { min-height: 44px; }
.lesson__nav .btn:only-child { margin-left: auto; }
/* Next and "Continue to the video" take the same room, so the button does not change size on the last step. */
.lesson__nav .btn--primary { min-width: 13.5rem; }
.lesson__nav .btn--quiet { min-width: 6.5rem; }

/* The video waits for the lesson: same box as the reel, so nothing jumps when it opens. */
.watch__locked {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: .75rem 1.25rem;
  padding: 1.25rem;
  border: 1px dashed var(--slate);
  border-radius: 2px;
  background: var(--card);
  max-width: var(--measure);
}
.watch__locked-msg { color: var(--slate); font-size: .9375rem; }
.watch__host:focus { outline: none; }

@media (prefers-reduced-motion: reduce) {
  .lesson__card { animation: none; }
  .lesson__seg-btn::before { transition: none; }
}

/* ---------- clips ---------- */

.watch { margin: 2rem 0; }

.watch__reel {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
  gap: var(--gap);
}

.clip { display: flex; flex-direction: column; gap: .6rem; }

/* The clip plays right here, in this same box - never a popup. .clip__frame
   is just the aspect-ratio-locked stage; its content swaps in place between
   a clickable poster (.clip__play-btn) and the live <video> (.player, see
   below) once playback starts. */
.clip__frame {
  position: relative;
  aspect-ratio: 16 / 9;
  width: 100%;
  border: 1px solid var(--hairline);
  border-radius: 2px;
  background: var(--ink);
  overflow: hidden;
}

.clip__play-btn {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}

.clip__poster {
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: .68;
  transition: opacity .2s ease, transform .4s ease;
}
.clip__play-btn:hover .clip__poster { opacity: .9; transform: scale(1.02); }

.clip__play {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  color: var(--ink);
}
.clip__play svg {
  width: 54px;
  height: 54px;
  padding: 14px;
  border-radius: 50%;
  background: var(--card);
  box-shadow: 0 2px 12px rgba(0, 0, 0, .35);
  transition: transform .2s ease;
}
.clip__play-btn:hover .clip__play svg { transform: scale(1.08); }

.clip__time {
  position: absolute;
  right: .5rem;
  bottom: .5rem;
  background: var(--ink);
  color: var(--card);
  font-family: var(--mono);
  font-size: .6875rem;
  padding: .15rem .4rem;
  border-radius: 2px;
}

.clip__meta { display: flex; flex-direction: column; gap: .15rem; }
.clip__title { font-size: .9375rem; font-weight: 600; }
.clip__credit { font-family: var(--mono); font-size: .6875rem; color: var(--slate); }

.clip__fallback {
  padding: 2rem;
  text-align: center;
  color: var(--card);
  display: grid;
  gap: 1rem;
  place-content: center;
  font-size: .9375rem;
}
.clip__fallback a { color: var(--tape); }

/* The player's own control bar (src/app.js buildControls): play/pause/replay, length as text, speed, captions, full
   screen. There is deliberately no seek bar, no progress display and no mute. While a video is live the frame stops
   being a fixed 16:9 box and stacks the picture and the bar, so captions and controls never cover each other. */
.clip__frame.is-live { aspect-ratio: auto; display: flex; flex-direction: column; background: #111; }
.clip__frame.is-live .player { height: auto; aspect-ratio: 16 / 9; flex: none; }
.clip__frame.is-live:fullscreen { height: 100%; }
.clip__frame.is-live:fullscreen .player { flex: 1 1 auto; min-height: 0; aspect-ratio: auto; object-fit: contain; }
.player-bar {
  flex: none;
  display: flex;
  align-items: center;
  gap: .35rem;
  padding: .15rem .5rem;
  background: #161A18;
  color: #fff;
}
.player-bar__btn {
  min-width: 44px;
  min-height: 44px;
  display: inline-grid;
  place-items: center;
  border: 0;
  border-radius: 2px;
  background: transparent;
  color: inherit;
  font-family: var(--mono);
  font-size: .8125rem;
  font-weight: 700;
  letter-spacing: .04em;
  cursor: pointer;
}
.player-bar__btn svg { width: 26px; height: 26px; }
.player-bar__btn:hover { background: rgba(255, 255, 255, .18); }
.player-bar__btn[aria-pressed="true"] { background: var(--tape); color: #161A18; }
.player-bar :focus-visible { outline: 3px solid #fff; outline-offset: -3px; }
.player-bar__length { font-family: var(--mono); font-size: .8125rem; font-variant-numeric: tabular-nums; }
.player-bar__spacer { flex: 1; }
.player-bar__speed { display: inline-flex; align-items: center; }
.player-bar__select {
  min-height: 44px;
  padding: 0 .4rem;
  border: 1px solid rgba(255, 255, 255, .55);
  border-radius: 2px;
  background: rgba(0, 0, 0, .55);
  color: #fff;
  font-family: var(--mono);
  font-size: .8125rem;
  cursor: pointer;
}
.player-bar__select option { color: #161A18; background: #fff; }

/* ---------- quiz ---------- */

.quiz {
  background: var(--card);
  border: 1px solid var(--hairline);
  border-radius: 2px;
  padding: clamp(1.25rem, 3vw, 1.75rem);
  margin: 2rem 0;
  max-width: var(--measure);
}

/* Stands in for .quiz until the module's video has been watched - same
   box, so nothing jumps around once the real quiz swaps in. */
.quiz--locked { display: flex; align-items: center; justify-content: center; min-height: 5rem; }
.quiz__locked-msg { color: var(--slate); font-size: .9375rem; text-align: center; }

.quiz__head {
  font-family: var(--serif);
  font-size: 1.375rem;
  font-weight: 600;
  margin-bottom: .25rem;
}
.quiz__intro {
  font-family: var(--mono);
  font-size: .75rem;
  color: var(--slate);
  margin-bottom: 1.5rem;
}

.question { border: 0; margin-bottom: 1.5rem; }
.question__prompt {
  font-size: .9375rem;
  font-weight: 600;
  line-height: 1.5;
  margin-bottom: .7rem;
  padding: 0;
}
.question__hint {
  font-family: var(--mono);
  font-size: .75rem;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--slate);
  margin: -.35rem 0 .7rem;
}

.question__options { display: flex; flex-direction: column; gap: .4rem; }

.option {
  display: flex;
  gap: .7rem;
  align-items: flex-start;
  padding: .7rem .85rem;
  border: 1px solid var(--hairline);
  border-radius: 2px;
  background: var(--concrete);
  cursor: pointer;
  font-size: .9375rem;
  line-height: 1.45;
  transition: border-color .15s ease, background .15s ease;
}
.option:hover { border-color: var(--ink); }
/* A crisp ink ring + heavier text so the chosen answer is unmistakable in
   every theme — in dark mode the checked/unchecked background delta alone
   is too subtle to carry the selection. */
.option:has(input:checked) {
  border-color: var(--ink);
  background: var(--card);
  box-shadow: inset 0 0 0 1px var(--ink);
  font-weight: 600;
}
.option input { margin-top: .3rem; flex: none; accent-color: var(--ink); }

.feedback {
  margin-top: .6rem;
  padding: .65rem .85rem;
  border-radius: 2px;
  font-size: .875rem;
  line-height: 1.5;
  border-left: 3px solid;
}
.feedback.is-right { border-color: var(--verify); background: rgba(20, 89, 74, .08); color: var(--verify); }
.feedback.is-wrong { border-color: var(--signal); background: rgba(194, 65, 12, .08); color: var(--signal); }
.feedback.is-blank { border-color: var(--slate); background: rgba(92, 99, 96, .08); color: var(--slate); }

.quiz__actions {
  display: flex;
  flex-wrap: wrap;
  gap: .75rem;
  align-items: center;
  padding-top: 1.25rem;
  border-top: 1px solid var(--hairline);
}
.quiz__result {
  font-family: var(--mono);
  font-size: .75rem;
  color: var(--slate);
}
.quiz__result.is-pass { color: var(--verify); font-weight: 700; }

/* ---------- pager ---------- */

.pager__lock {
  border-left: 3px solid var(--signal);
  background: rgba(194, 65, 12, .08);
  color: var(--signal);
  padding: .65rem .85rem;
  border-radius: 0 2px 2px 0;
  font-size: .875rem;
  line-height: 1.5;
  margin-bottom: 1rem;
}
.pager__lock[hidden] { display: none; }

@keyframes pager-lock-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(194, 65, 12, 0); }
  30% { box-shadow: 0 0 0 4px rgba(194, 65, 12, .3); }
}
.pager__lock.is-pulsing { animation: pager-lock-pulse .6s ease; }

.pager {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--hairline);
}
.pager__pos { font-family: var(--mono); font-size: .75rem; color: var(--slate); }

/* ---------- course picker (multi-course, before one is selected) ---------- */

.course-picker {
  margin-top: 2rem;
  padding: 1.5rem;
  border: 1px solid var(--hairline);
  border-radius: 2px;
  background: var(--card);
  max-width: var(--measure);
}
.course-picker h2 { margin-bottom: .4rem; }
.course-picker p { color: var(--slate); margin-bottom: 1.2rem; }
.course-picker__list {
  display: flex;
  flex-direction: column;
  gap: .6rem;
}
.course-picker__option { align-self: flex-start; }

/* add-on apps the organization has bought: a panel of tiles under the header */
.apps-panel { margin-bottom: 1.5rem; }
.apps-panel__hint { color: var(--slate); margin: 0 0 1rem; }
.apps-panel__list { display: grid; gap: .75rem; grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); }
.apps-panel__tile {
  display: flex; flex-direction: column; align-items: flex-start; gap: .25rem; text-align: left;
  padding: .9rem 1rem; border-left: 5px solid var(--tape);
}
.apps-panel__tile span { color: var(--slate); font-size: .92rem; font-weight: 400; }

.course-checkbox-list {
  display: flex;
  flex-direction: column;
  gap: .3rem;
}
.course-checkbox-list__item {
  display: flex;
  align-items: center;
  gap: .4rem;
  font-weight: 400;
}

/* ---------- completion ---------- */

.done {
  margin-top: 2rem;
  padding: 1.5rem;
  border: 2px solid var(--verify);
  border-radius: 2px;
  background: var(--card);
  max-width: var(--measure);
}
.done__mark {
  font-family: var(--mono);
  font-size: .75rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--verify);
  font-weight: 700;
  margin-bottom: .4rem;
}
#doneOfflineNote, #doneSessionNote {
  margin-bottom: .9rem;
}

/* ---------- footer ---------- */

.foot {
  border-top: 1px solid var(--hairline);
  background: var(--card);
  padding: 1.5rem var(--edge);
  text-align: center;
}
.foot p {
  font-family: var(--mono);
  font-size: .6875rem;
  color: var(--slate);
  line-height: 1.7;
}

/* ---------- modal ---------- */

.modal {
  position: fixed;
  inset: 0;
  background: rgba(22, 26, 24, .82);
  z-index: 100;
  display: grid;
  place-items: center;
  padding: var(--edge);
}
.modal[hidden] { display: none; }

.modal__box {
  background: var(--card);
  border-radius: 2px;
  width: min(900px, 100%);
  max-height: 90vh;
  overflow: auto;
  border-top: 4px solid var(--tape);
}

.modal__head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 1rem;
  padding: 1.1rem 1.25rem;
  border-bottom: 1px solid var(--hairline);
}
.modal__title { font-family: var(--serif); font-size: 1.25rem; font-weight: 600; }
.modal__credit { font-family: var(--mono); font-size: .6875rem; color: var(--slate); margin-top: .2rem; }

.modal__stage { background: var(--ink); aspect-ratio: 16 / 9; }
.player { width: 100%; height: 100%; display: block; }

.modal__body { padding: 1.25rem; }

/* Confirm/alert dialogs (e.g. #confirmModal) reuse .modal/.modal__box but
   don't need the 900px width meant for the badge-detail modal's content. */
#confirmModal .modal__box { width: min(420px, 100%); }
.modal__actions { display: flex; justify-content: flex-end; gap: .75rem; margin-top: 1.25rem; }

/* ---------- beta feedback form (certificate page) ---------- */
.feedback-box { width: min(640px, 100%); }
/* the form and the thanks panel set their own display, which would otherwise beat the hidden attribute */
.feedback-box [hidden] { display: none !important; }
.feedback-item { border: 1px solid var(--hairline); border-radius: 4px; padding: 1rem; margin-bottom: 1rem; display: grid; gap: .75rem; }
.feedback-item legend { padding: 0 .4rem; }
.feedback-item textarea { resize: vertical; min-height: 6rem; }
.feedback-count { display: block; margin-top: .25rem; font-family: var(--mono); font-size: .6875rem; color: var(--slate); text-align: right; }
.feedback-actions { display: flex; flex-wrap: wrap; gap: .75rem; margin-top: 1rem; }
.feedback-actions .btn, .feedback-box .form > .btn { min-height: 44px; width: auto; }
.feedback-box .modal__head .btn { white-space: nowrap; }
.feedback-thanks__title { font-family: var(--serif); font-size: 1.5rem; margin-bottom: .5rem; }
@media print { #feedbackBtn, #feedbackModal { display: none !important; } }

/* ---------- beta welcome card ----------
   One card, shown once per sign-in to a beta participant. A brand ribbon (the logo on a tape-coloured band with a fine diagonal
   weave and one pass of light), a star seal beside the welcome, a serif headline with a tape underline, three "coming soon" tiles
   that carry the new add-on logo and two line icons, a referral panel whose code reads like a ticket, and the terms panel that
   asks for attention until it is answered. The parts rise in one after another. Everything uses the page's own tokens, so it
   follows the light, default and dark themes, and everything that moves stops for anyone who asks for less motion. */
.beta-card {
  position: relative;
  width: min(700px, 100%);
  max-height: 92vh;
  overflow: auto;
  background: var(--card);
  border-radius: 18px;
  box-shadow: 0 40px 110px rgba(0, 0, 0, .5), 0 0 0 1px var(--hairline);
  animation: beta-in .5s cubic-bezier(.2, .8, .3, 1) both;
  scrollbar-width: thin;
}
@keyframes beta-in {
  from { opacity: 0; transform: translateY(20px) scale(.98); }
  to { opacity: 1; transform: none; }
}
@keyframes beta-rise {
  from { opacity: 0; transform: translateY(14px); }
  to { opacity: 1; transform: none; }
}
@keyframes beta-sheen {
  from { transform: translateX(-130%); }
  to { transform: translateX(130%); }
}
.beta-card :focus-visible { outline: 3px solid var(--tape); outline-offset: 2px; border-radius: 4px; }
.beta-card__ribbon {
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1.2rem 3.5rem 1.2rem 1.5rem;
  background:
    repeating-linear-gradient(135deg, rgba(255, 255, 255, .24) 0 2px, transparent 2px 10px),
    radial-gradient(120% 220% at 100% 0%, rgba(255, 255, 255, .5), transparent 55%),
    linear-gradient(100deg, var(--tape) 0%, color-mix(in srgb, var(--tape) 80%, #fff) 100%);
  border-bottom: 1px solid rgba(0, 0, 0, .16);
}
.beta-card__ribbon::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(110deg, transparent 38%, rgba(255, 255, 255, .45) 50%, transparent 62%);
  transform: translateX(-130%);
  animation: beta-sheen 2.6s ease .7s 1 both;
  pointer-events: none;
}
.beta-card__ribbon .brand-logo {
  position: relative;
  z-index: 1;
  height: 2.6rem;
  background: var(--card);
  padding: .32rem .75rem;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, .18);
}
.beta-card__badge {
  position: relative;
  z-index: 1;
  font-family: var(--mono);
  font-size: .6875rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  font-weight: 700;
  color: #161A18;
  background: rgba(255, 255, 255, .62);
  padding: .34rem .7rem;
  border-radius: 999px;
}
.beta-card__x {
  position: absolute;
  z-index: 2;
  top: .6rem;
  right: .65rem;
  width: 2.75rem;
  height: 2.75rem;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: #161A18;
  font-size: 1.6rem;
  line-height: 1;
  cursor: pointer;
  transition: background .15s ease, transform .15s ease;
}
.beta-card__x:hover { background: rgba(255, 255, 255, .55); transform: rotate(90deg); }
.beta-card__body { padding: clamp(1.4rem, 4vw, 2.2rem); display: grid; gap: 1.25rem; }
.beta-card__body > * { animation: beta-rise .55s cubic-bezier(.2, .8, .3, 1) both; }
.beta-card__body > :nth-child(1) { animation-delay: .12s; }
.beta-card__body > :nth-child(2) { animation-delay: .2s; }
.beta-card__body > :nth-child(3) { animation-delay: .28s; }
.beta-card__body > :nth-child(4) { animation-delay: .36s; }
.beta-card__body > :nth-child(5) { animation-delay: .44s; }
.beta-card__body > :nth-child(6) { animation-delay: .52s; }
.beta-card__body > :nth-child(7) { animation-delay: .6s; }
.beta-card__hero { display: flex; align-items: center; gap: .8rem; }
.beta-card__seal {
  flex: none;
  width: 2.6rem;
  height: 2.6rem;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: radial-gradient(circle at 32% 28%, color-mix(in srgb, var(--tape) 55%, #fff), var(--tape) 62%, color-mix(in srgb, var(--tape) 78%, #000));
  box-shadow: 0 4px 12px color-mix(in srgb, var(--tape) 55%, transparent), inset 0 1px 0 rgba(255, 255, 255, .6);
}
.beta-card__seal svg { width: 1.35rem; height: 1.35rem; fill: #161A18; }
.beta-card__eyebrow {
  font-family: var(--mono);
  font-size: .75rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--tape-text);
  font-weight: 700;
}
.beta-card__title {
  font-family: var(--serif);
  font-size: clamp(1.7rem, 4.8vw, 2.3rem);
  line-height: 1.1;
  letter-spacing: -.015em;
  font-weight: 600;
  text-wrap: balance;
}
.beta-card__title::after {
  content: "";
  display: block;
  width: 3.6rem;
  height: 5px;
  margin-top: .75rem;
  border-radius: 3px;
  background: linear-gradient(90deg, var(--tape), color-mix(in srgb, var(--tape) 40%, transparent));
}
.beta-card__lead { font-size: 1.0625rem; line-height: 1.65; max-width: 58ch; color: var(--ink); }
.beta-card__panel {
  display: grid;
  gap: .75rem;
  padding: 1.2rem 1.35rem;
  background: var(--concrete);
  border: 1px solid var(--hairline);
  border-left: 5px solid var(--tape);
  border-radius: 12px;
}
.beta-card__panel p { font-size: .9375rem; line-height: 1.6; }
.beta-card__h {
  font-family: var(--mono);
  font-size: .75rem;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--slate);
  font-weight: 700;
}
.beta-card__panel--terms { border-left-color: var(--ink); box-shadow: 0 0 0 3px color-mix(in srgb, var(--tape) 35%, transparent); }
.beta-card__soon { list-style: none; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .75rem; }
.beta-card__soon li {
  display: grid;
  align-content: start;
  gap: .3rem;
  padding: .95rem 1rem 1rem;
  background: var(--card);
  border: 1px solid var(--hairline);
  border-radius: 12px;
  transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
.beta-card__soon li:hover { border-color: var(--tape); box-shadow: 0 8px 22px rgba(0, 0, 0, .12); transform: translateY(-2px); }
.beta-card__soon-icon {
  width: 3.5rem;
  height: 3.5rem;
  margin: -.1rem 0 .25rem -.25rem;
  display: grid;
  place-items: center;
}
.beta-card__soon-icon img { width: 100%; height: 100%; filter: drop-shadow(0 5px 6px rgba(0, 0, 0, .22)); }
.beta-card__soon-icon--line {
  width: 2.75rem;
  height: 2.75rem;
  margin: .4rem 0 .35rem 0;
  border-radius: 12px;
  background: color-mix(in srgb, var(--tape) 22%, var(--card));
  border: 1px solid color-mix(in srgb, var(--tape) 45%, transparent);
}
.beta-card__soon-icon svg { width: 1.5rem; height: 1.5rem; fill: none; stroke: var(--ink); stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.beta-card__soon strong { font-family: var(--serif); font-size: 1.0625rem; line-height: 1.2; }
.beta-card__soon li > span:not(.beta-card__soon-icon) { font-size: .875rem; line-height: 1.45; color: var(--slate); }
.beta-card [hidden] { display: none !important; }
.beta-card__hint { font-size: .875rem; color: var(--muted, inherit); margin-top: .5rem; }
.beta-card__request { display: flex; flex-wrap: wrap; align-items: center; gap: .75rem 1rem; }
.beta-card__request .check { flex: 1 1 15rem; }
.beta-card__request .btn { min-height: 44px; }
.beta-card__code {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .6rem 1rem;
  padding: 1rem 1.15rem;
  background: linear-gradient(135deg, var(--card), color-mix(in srgb, var(--tape) 12%, var(--card)));
  border: 2px dashed var(--tape);
  border-radius: 12px;
  animation: beta-in .4s ease both;
}
.beta-card__code[hidden] { display: none; }
.beta-card__code-label {
  flex: 1 0 100%;
  font-family: var(--mono);
  font-size: .6875rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--slate);
}
.beta-card__code-value {
  font-family: var(--mono);
  font-size: clamp(1.5rem, 5.4vw, 2rem);
  font-weight: 700;
  letter-spacing: .22em;
  color: var(--ink);
  user-select: all;
}
.beta-card__code-note { flex: 1 0 100%; font-size: .85rem; color: var(--slate); }
.beta-card__actions { display: flex; justify-content: flex-end; }
.beta-card__actions .btn { min-height: 44px; min-width: 7.5rem; }
@media (max-width: 40rem) {
  .beta-card { border-radius: 14px; }
  .beta-card__soon { grid-template-columns: minmax(0, 1fr); }
  .beta-card__soon li { grid-template-columns: auto minmax(0, 1fr); column-gap: .85rem; align-items: center; }
  .beta-card__soon-icon { grid-row: span 2; margin: 0; }
  .beta-card__soon-icon--line { margin: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .beta-card, .beta-card__code, .beta-card__body > *, .beta-card__ribbon::after { animation: none; }
  .beta-card__x, .beta-card__soon li { transition: none; }
  .beta-card__x:hover { transform: none; }
  .beta-card__soon li:hover { transform: none; }
}

/* ---------- admin (SuperAdmin/OrgAdmin) ---------- */

/* The three registered/started/completed counts on the course dashboard -
   each one doubles as the button that drills into that category's list
   (orgadmin-course.js). */
.stat-row { display: flex; gap: .75rem; flex-wrap: wrap; margin: 1rem 0; }

.admin-table {
  width: 100%;
  border-collapse: collapse;
  font-size: .9375rem;
  margin: 1rem 0;
}
.admin-table th {
  font-family: var(--mono);
  font-size: .6875rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--slate);
  font-weight: 500;
  text-align: left;
  padding: .5rem .75rem;
  border-bottom: 1px solid var(--hairline);
}
.admin-table td {
  padding: .6rem .75rem;
  border-bottom: 1px solid var(--hairline);
  vertical-align: middle;
}
.admin-table tr:last-child td { border-bottom: none; }
.admin-table .meter { width: 100px; margin: .3rem 0 0; }
.admin-table td .btn { margin: .15rem .4rem .15rem 0; }
.admin-table td { overflow-wrap: break-word; }
/* the action column used to be nowrap and pushed wide tables past their panel; its buttons now wrap */
.admin-table td:last-child { white-space: normal; }
.panel { min-width: 0; }

/* ---------- admin grids (2026-10-20) ----------
   Every admin table sits in .table-wrap: if a table is still wider than its panel it scrolls inside the wrap instead of spilling over the
   neighbouring panel. On a phone each row becomes a card whose cells show their column name (src/gridlabels.js sets the data-label). */
.table-wrap { max-width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; margin: 1rem 0; }
.table-wrap > .admin-table { margin: 0; }
@media (max-width: 640px) {
  .table-wrap { overflow-x: visible; }
  .table-wrap > .admin-table, .table-wrap > .admin-table tbody { display: block; }
  .table-wrap > .admin-table thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .table-wrap > .admin-table tbody tr { display: block; border: 1px solid var(--hairline); border-radius: 8px; padding: .4rem .8rem; margin: .6rem 0; }
  .table-wrap > .admin-table tbody tr[hidden] { display: none; }
  .table-wrap > .admin-table tbody td { display: flex; gap: .75rem; justify-content: space-between; align-items: baseline; border-bottom: 0; padding: .3rem 0; text-align: right; }
  .table-wrap > .admin-table tbody td::before { content: attr(data-label); flex: 0 0 38%; text-align: left; font-family: var(--mono); font-size: .6875rem; letter-spacing: .1em; text-transform: uppercase; color: var(--slate); }
  .table-wrap > .admin-table tbody td[data-label=""]::before { content: none; }
  .table-wrap > .admin-table tbody td:last-child { justify-content: flex-start; flex-wrap: wrap; text-align: left; }
  .table-wrap > .admin-table tbody td[colspan] { display: block; text-align: left; }
  .table-wrap > .admin-table tbody td[colspan]::before { content: none; }
}

.credential-value {
  display: inline-block;
  font-family: var(--mono);
  font-size: 1rem;
  background: var(--concrete);
  border: 1px solid var(--hairline);
  border-radius: 2px;
  padding: .4rem .6rem;
  user-select: all;
}

/* Repeating-row editor (gamification rules) */

.rule-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: .75rem;
  margin: .75rem 0 1.5rem;
}

.rule-list { display: flex; flex-direction: column; gap: .5rem; margin: .75rem 0; }

.rule-row {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  align-items: flex-end;
  padding: .6rem;
  border: 1px solid var(--hairline);
  border-radius: 2px;
  background: var(--concrete);
}
.rule-row .form__group { flex: 1 1 100px; min-width: 0; margin: 0; }
.rule-row .form__group--wide { flex: 2 1 180px; }
.rule-row .btn--remove { flex: 0 0 auto; border-color: var(--signal); color: var(--signal); }

.rules-status { font-family: var(--mono); font-size: .8125rem; color: var(--slate); margin: .5rem 0 1rem; }

.course-content__correct { color: var(--verify); font-weight: 700; }
.course-content__explanation { color: var(--slate); font-size: .875rem; font-style: italic; margin: .25rem 0 1rem; }

.rules-actions {
  display: flex;
  gap: .75rem;
  margin-top: 1.5rem;
  padding-top: 1rem;
  border-top: 1px solid var(--hairline);
}

/* ---------- responsive ---------- */

@media (max-width: 760px) {
  .strip { grid-template-columns: repeat(10, minmax(0, 1fr)); }
  .bar__inner { align-items: flex-start; }
  .bar__tools { width: 100%; justify-content: space-between; }
  .pager { flex-wrap: wrap; }
}

@media (max-width: 420px) {
  .strip { grid-template-columns: repeat(7, minmax(0, 1fr)); }
  /* Was height: 34px here - silently undid the base rule's 44px
     touch-target fix on exactly the narrow-phone widths that fix was
     for. 7 columns still leaves plenty of width per cell at this
     breakpoint, so there's no layout reason to shrink the height too. */
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; scroll-behavior: auto !important; }
}

@media print {
  .track, .bar__tools, .pager, .quiz__actions, .modal, .skip, .scroll-cue { display: none; }
  body { background: #fff; }
  .panel, .quiz { border-color: #999; }
}

/* ---------- auth / login page ---------- */

.auth {
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: var(--edge);
}
.auth[hidden] { display: none; }

.auth__box {
  width: min(420px, 100%);
  background: var(--card);
  border: 1px solid var(--hairline);
  border-top: 4px solid var(--tape);
  border-radius: 2px;
  padding: clamp(1.5rem, 5vw, 2.25rem);
}

.auth__brand { display: flex; gap: 1rem; align-items: stretch; margin-bottom: 1.5rem; }

.auth__title {
  font-family: var(--serif);
  font-size: 1.5rem;
  font-weight: 600;
  letter-spacing: -.01em;
  line-height: 1.2;
}

.auth__sub { font-family: var(--mono); font-size: .75rem; color: var(--slate); margin-top: .2rem; }

.form { display: flex; flex-direction: column; gap: 1rem; margin-top: 1.5rem; }

.form__group { display: flex; flex-direction: column; gap: .3rem; }

.form__label {
  font-family: var(--mono);
  font-size: .6875rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--slate);
}

.input {
  font-family: var(--sans);
  font-size: .9375rem;
  padding: .7rem .85rem;
  border: 1px solid var(--ink);
  border-radius: 2px;
  background: var(--concrete);
  color: var(--ink);
}

.form__error {
  border-left: 3px solid var(--signal);
  background: rgba(194, 65, 12, .08);
  color: var(--signal);
  padding: .65rem .85rem;
  border-radius: 0 2px 2px 0;
  font-size: .875rem;
  line-height: 1.5;
}
.form__error[hidden] { display: none; }

.form .btn--primary { width: 100%; padding: .8rem 1.1rem; }

/* Every auth page (login, forgot-password, superadmin's own login) follows
   a form immediately with a bordered .btn--quiet link ("Forgot password?",
   "Back to sign in") - with no gap, that link's top border sits flush
   against the primary button's bottom edge and reads as overlapping it. */
.auth__box .form + p, .auth__box .form + details { margin-top: .85rem; }
.auth__box details > .rules-status { margin-top: .6rem; }

.auth__divider {
  display: flex;
  align-items: center;
  gap: .75rem;
  margin: 1.5rem 0;
  font-family: var(--mono);
  font-size: .6875rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--slate);
}
.auth__divider::before,
.auth__divider::after { content: ""; flex: 1; height: 1px; background: var(--hairline); }
.auth__divider[hidden] { display: none; }

.auth__sso .btn { width: 100%; }
.auth__sso[hidden] { display: none; }

/* ---------- gamification ---------- */

/* Header chip: .tag's mono/uppercase typography plus button chrome, so it
   reads as a small clickable badge rather than a plain label. */
.rank-chip {
  font-family: var(--mono);
  font-size: .6875rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink);
  background: var(--card);
  border: 1px solid var(--tape);
  border-radius: 2px;
  padding: .55rem .7rem;
  cursor: pointer;
  transition: background .15s ease, color .15s ease;
}
.rank-chip:hover { background: var(--tape); color: var(--ink); }
.rank-chip[hidden] { display: none; }
/* A chip that opens a bigger screen carries a small circled "i", so nobody has to guess that it can be selected. */
.rank-chip--detail::after {
  content: "i";
  display: inline-grid;
  place-items: center;
  width: 1.15em;
  height: 1.15em;
  margin-left: .55em;
  border: 1px solid currentColor;
  border-radius: 50%;
  font-family: var(--serif);
  font-style: italic;
  font-weight: 700;
  font-size: .85em;
  letter-spacing: 0;
  text-transform: none;
  vertical-align: middle;
}

/* Score breakdown: same card as .panel, own label/value grid. Wrapped in
   <details>/<summary> so it starts collapsed and only opens on request -
   nothing here should force it open, that's the whole point. */
.score-panel {
  margin-top: 2rem;
  max-width: var(--measure);
}
.score-panel__summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .5rem;
  cursor: pointer;
  list-style: none;
  margin-bottom: 0;
}
.score-panel__summary::-webkit-details-marker { display: none; }
.score-panel__summary::after {
  content: "\25B8"; /* ▸ */
  color: var(--slate);
  transition: transform .15s ease;
}
.score-panel__summary:hover,
.score-panel__summary:hover::after { color: var(--ink); }
.score-panel__details[open] .score-panel__summary { margin-bottom: .85rem; }
.score-panel__details[open] .score-panel__summary::after { transform: rotate(90deg); }
.score-panel__grid {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: .5rem 1rem;
}
.score-panel__grid dt {
  font-size: .9375rem;
  color: var(--slate);
}
.score-panel__grid dd {
  font-family: var(--mono);
  font-size: .9375rem;
  font-weight: 600;
  text-align: right;
}
.score-panel__grid dt:last-of-type,
.score-panel__grid dd:last-of-type {
  border-top: 1px solid var(--hairline);
  padding-top: .5rem;
  margin-top: .15rem;
  color: var(--ink);
  font-weight: 700;
}

/* Rank-up (default style): no card, no border - just the words themselves,
   rising with a fading afterimage trail behind them and disappearing, the
   way a game announces a level gained. app.js builds this dynamically
   (spawning and independently fading a ghost copy every ~50ms as the main
   text rises via requestAnimationFrame - see showRankUpFloatFade), the
   same way the five Phase C3 presets below build their own markup; only
   the base classes live here. The one thing that changes per theme is
   --halo (defined alongside the other theme tokens near the top of this
   file): a dark halo on the light/default paper so the gold doesn't wash
   out, a soft light glow on the dark ground so it doesn't vanish into it -
   the gold fill and the motion itself never change. */
.levelup {
  position: fixed;
  left: 50%;
  top: 32%;
  z-index: 150;
  text-align: center;
  pointer-events: none;
}
.levelup__eyebrow {
  display: block;
  font-family: var(--mono);
  font-size: 1.0625rem;
  font-weight: 700;
  letter-spacing: .32em;
  /* Fixed, not a theme token on purpose - unlike --card (a surface colour
     that inverts dark/light with the theme), this needs to stay light in
     all three themes so it reads the same against --halo every time; only
     the halo itself is meant to vary. */
  color: rgba(255, 255, 255, .95);
  text-shadow: 0 1px 2px var(--halo), 0 0 10px var(--halo);
}
.levelup__title {
  display: block;
  font-family: var(--serif);
  font-size: 2.5rem;
  font-weight: 600;
  color: var(--tape);
  text-shadow: 0 2px 4px var(--halo), 0 0 20px var(--halo);
}

/* Badge unlock toast: bottom-corner, stays until dismissed or clicked
   through to the detail modal (app.js hides it on either). Two separate
   buttons side by side - .badge-toast__btn opens the detail modal,
   .badge-toast__close just dismisses - so the card and border/shadow live
   on the shared .badge-toast wrapper, not either button individually. */
.badge-toast {
  position: fixed;
  bottom: var(--edge);
  right: var(--edge);
  z-index: 150;
  max-width: min(360px, calc(100vw - 2 * var(--edge)));
  display: flex;
  align-items: flex-start;
  background: var(--card);
  border: 2px solid var(--tape);
  border-radius: 2px;
  box-shadow: 0 12px 40px rgba(0, 0, 0, .25);
}
.badge-toast[hidden] { display: none; }
.badge-toast { transition: bottom .25s ease; }
@media (prefers-reduced-motion: reduce) { .badge-toast { transition: none; } }
/* The second line says that selecting the card opens more: an arrow, in the page's accent colour, underlined on hover. */
.badge-toast__hint {
  display: block;
  margin-top: .2rem;
  font-family: var(--mono);
  font-size: .75rem;
  letter-spacing: .04em;
  color: var(--tape-text);
}
.badge-toast__hint::after { content: " \2192"; }
.badge-toast__btn:hover .badge-toast__hint { text-decoration: underline; }
.badge-toast__btn {
  display: flex;
  align-items: center;
  gap: .75rem;
  flex: 1 1 auto;
  min-width: 0;
  text-align: left;
  padding: 1rem 1.1rem;
  background: none;
  border: 0;
  cursor: pointer;
  font-family: var(--sans);
  color: var(--ink);
}
.badge-toast__emoji { font-size: 1.75rem; line-height: 1; flex: none; }
.badge-toast__text { font-size: .875rem; line-height: 1.4; }

.badge-toast__close {
  flex: none;
  width: 2.75rem; /* was 1.75rem (28px) - under the ~44px touch-target guideline */
  height: 2.75rem;
  margin: .1rem .1rem 0 0;
  display: grid;
  place-items: center;
  background: none;
  border: 0;
  border-radius: 2px;
  color: var(--slate);
  font-size: 1.25rem;
  line-height: 1;
  cursor: pointer;
}
.badge-toast__close:hover { background: var(--concrete); color: var(--ink); }

/* Badge detail modal: reuses .modal/.modal__box, but .modal__stage was
   built for a 16:9 dark video frame - override it back to plain card
   content for a text+emoji body. */
.badge-modal__body {
  aspect-ratio: auto;
  background: var(--card);
  padding: 2.5rem 1.5rem;
  text-align: center;
}
.badge-modal__emoji { font-size: 3rem; line-height: 1; margin-bottom: 1rem; }

/* Framework links: which NIST CSF / CIS / ISO items a module teaches.
   Collapsed reference, deliberately quieter than the lesson panels. */
.framework-links {
  margin: 1.25rem 0 0;
  padding: .75rem 1rem;
  border: 1px solid var(--concrete);
  border-radius: 2px;
  font-size: .875rem;
}
.framework-links__summary {
  cursor: pointer;
  font-family: var(--mono);
  font-size: .6875rem;
  letter-spacing: .1em;
  text-transform: uppercase;
}
.framework-links__row { margin: .6rem 0 0; overflow-wrap: anywhere; }
.framework-links__name { font-weight: 600; }

/* Badge shelf modal (badge-only courses, e.g. leadership training): every
   badge in the course, earned ones in full colour, locked ones dimmed. State
   is also spelled out in text on each item, never colour alone. */
.badge-shelf__body {
  aspect-ratio: auto;
  background: var(--card);
  padding: 1rem 1.25rem 1.5rem;
  max-height: 70vh;
  overflow-y: auto;
}
.badge-shelf {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: .75rem;
}
.badge-shelf__item {
  display: grid;
  grid-template-columns: 2.5rem 1fr;
  column-gap: .9rem;
  align-items: start;
  padding: .75rem .9rem;
  border: 1px solid var(--concrete);
  border-radius: 2px;
}
.badge-shelf__item.is-earned { border-color: var(--tape); }
.badge-shelf__item.is-locked { opacity: .62; }
.badge-shelf__emoji { font-size: 1.9rem; line-height: 1.1; }
.badge-shelf__item.is-locked .badge-shelf__emoji { filter: grayscale(1); }
.badge-shelf__name { font-weight: 600; margin: 0; }
.badge-shelf__desc { margin: .15rem 0 0; font-size: .9rem; }
.badge-shelf__state {
  margin: .3rem 0 0;
  font-family: var(--mono);
  font-size: .6875rem;
  letter-spacing: .1em;
  text-transform: uppercase;
}

/* ---------- animation-style presets (Phase C3) ---------- */
/* Each preset renders BOTH the rank-up and badge-unlock moments with one
   cohesive visual language (see showRankUpAnimation/showBadgeToast's
   dispatch in app.js), parameterized by icon/title/subtitle rather than
   built as ten separate implementations. The shipped default (.rankup/
   .badge-toast above) is its own untouched style, not one of these five. */

/* Confetti burst */
.confetti {
  position: fixed;
  inset: 0;
  z-index: 150;
  pointer-events: none;
  display: grid;
  place-items: center;
}
.confetti__piece {
  position: absolute;
  top: -10px;
  width: 8px;
  height: 14px;
  animation-name: confetti-fall;
  animation-timing-function: ease-in;
  animation-fill-mode: forwards;
}
@keyframes confetti-fall {
  0%   { transform: translateY(0) rotate(0deg); opacity: 1; }
  100% { transform: translateY(70vh) rotate(var(--rotate-end, 360deg)); opacity: 0; }
}
.confetti__card {
  text-align: center;
  padding: 1.5rem 2.5rem;
  background: var(--card);
  border: 2px solid var(--tape);
  border-radius: 2px;
  box-shadow: 0 12px 40px rgba(0, 0, 0, .25);
  pointer-events: auto;
  animation: confetti-card-pop 2.2s ease-out forwards;
}
@keyframes confetti-card-pop {
  0%   { transform: scale(.85); opacity: 0; }
  15%  { transform: scale(1); opacity: 1; }
  80%  { transform: scale(1); opacity: 1; }
  100% { transform: scale(1); opacity: 0; }
}
.confetti__icon { display: block; font-size: 2rem; margin-bottom: .35rem; }
.confetti__title { display: block; font-family: var(--serif); font-size: 1.5rem; font-weight: 600; color: var(--ink); }
.confetti__subtitle {
  display: block; font-family: var(--mono); font-size: .9375rem; letter-spacing: .12em;
  text-transform: uppercase; color: var(--slate); margin-top: .35rem;
}

/* Toast slide-in */
.toast-slide {
  position: fixed;
  bottom: var(--edge);
  right: var(--edge);
  z-index: 150;
  display: flex;
  align-items: center;
  gap: .75rem;
  max-width: min(360px, calc(100vw - 2 * var(--edge)));
  padding: 1rem 1.1rem;
  background: var(--card);
  border-left: 4px solid var(--tape);
  border-radius: 2px;
  box-shadow: 0 12px 40px rgba(0, 0, 0, .25);
  animation: toast-slide 2.6s cubic-bezier(.16, 1, .3, 1) forwards;
}
@keyframes toast-slide {
  0%   { transform: translateX(calc(100% + var(--edge))); opacity: 0; }
  10%  { transform: translateX(0); opacity: 1; }
  85%  { transform: translateX(0); opacity: 1; }
  100% { transform: translateX(calc(100% + var(--edge))); opacity: 0; }
}
.toast-slide__icon { font-size: 1.75rem; line-height: 1; flex: none; }
.toast-slide__text { display: flex; flex-direction: column; gap: .15rem; }
.toast-slide__title { font-family: var(--sans); font-size: .9375rem; font-weight: 600; color: var(--ink); }
.toast-slide__subtitle { font-family: var(--mono); font-size: .9375rem; letter-spacing: .1em; text-transform: uppercase; color: var(--slate); }

/* Modal bounce */
.modal-bounce {
  position: fixed;
  inset: 0;
  z-index: 150;
  display: grid;
  place-items: center;
  background: rgba(22, 26, 24, .55);
  animation: modal-bounce-backdrop 2.2s ease-out forwards;
  pointer-events: none;
}
@keyframes modal-bounce-backdrop {
  0%   { opacity: 0; }
  12%  { opacity: 1; }
  80%  { opacity: 1; }
  100% { opacity: 0; }
}
.modal-bounce__card {
  text-align: center;
  padding: 2rem 3rem;
  background: var(--card);
  border-top: 4px solid var(--tape);
  border-radius: 2px;
  box-shadow: 0 12px 40px rgba(0, 0, 0, .35);
  pointer-events: auto;
  animation: modal-bounce-card 2.2s cubic-bezier(.34, 1.56, .64, 1) forwards;
}
@keyframes modal-bounce-card {
  0%   { transform: scale(.4); opacity: 0; }
  18%  { transform: scale(1.05); opacity: 1; }
  28%  { transform: scale(1); opacity: 1; }
  80%  { transform: scale(1); opacity: 1; }
  100% { transform: scale(.9); opacity: 0; }
}
.modal-bounce__icon { display: block; font-size: 2.5rem; margin-bottom: .5rem; }
.modal-bounce__title { display: block; font-family: var(--serif); font-size: 1.75rem; font-weight: 600; color: var(--ink); }
.modal-bounce__subtitle {
  display: block; font-family: var(--mono); font-size: .9375rem; letter-spacing: .12em;
  text-transform: uppercase; color: var(--slate); margin-top: .4rem;
}

/* Badge flip */
.badge-flip {
  position: fixed;
  top: 30%;
  left: 50%;
  z-index: 150;
  transform: translate(-50%, -50%);
  perspective: 900px;
  pointer-events: none;
}
.badge-flip__card {
  position: relative;
  overflow: hidden;
  text-align: center;
  padding: 1.5rem 2.5rem;
  background: var(--card);
  border: 2px solid var(--tape);
  border-radius: 2px;
  box-shadow: 0 12px 40px rgba(0, 0, 0, .25);
  pointer-events: auto;
  animation: badge-flip-in 2.2s cubic-bezier(.2, .8, .3, 1) forwards;
}
@keyframes badge-flip-in {
  0%   { transform: rotateY(90deg); opacity: 0; }
  25%  { transform: rotateY(0deg); opacity: 1; }
  80%  { transform: rotateY(0deg); opacity: 1; }
  100% { transform: rotateY(-90deg); opacity: 0; }
}
.badge-flip__icon { display: block; font-size: 2rem; margin-bottom: .35rem; }
.badge-flip__title { display: block; font-family: var(--serif); font-size: 1.5rem; font-weight: 600; color: var(--ink); }
.badge-flip__subtitle {
  display: block; font-family: var(--mono); font-size: .9375rem; letter-spacing: .12em;
  text-transform: uppercase; color: var(--slate); margin-top: .35rem;
}
.badge-flip__shine {
  position: absolute;
  inset: 0;
  background: linear-gradient(115deg, transparent 40%, rgba(255, 255, 255, .5) 50%, transparent 60%);
  transform: translateX(-100%);
  animation: badge-flip-shine 2.2s ease-out forwards;
}
@keyframes badge-flip-shine {
  0%, 25% { transform: translateX(-100%); }
  45%     { transform: translateX(100%); }
  100%    { transform: translateX(100%); }
}

/* Progress-bar glow: no popup - the meter itself pulses at the trigger
   moment, using the meter's own --verify color so the glow reads as
   "more of the same," not a new visual language grafted onto it. */
.meter__fill.is-glowing { animation: meter-glow 1.8s ease-out; }
@keyframes meter-glow {
  0%   { box-shadow: 0 0 0 0 transparent; }
  30%  { box-shadow: 0 0 12px 4px var(--verify); }
  100% { box-shadow: 0 0 0 0 transparent; }
}

/* Completion certificate. Same "printed manual" language as the rest of
   the course - serif type, --tape as the one accent, sharp corners - just
   dressed up for a document meant to be kept, not just read once. The
   corner flourishes and rule are drawn in CSS (border segments + a single
   ornamental line), not an image, so it prints crisply at any size and
   needs no asset. */
.cert-stage {
  max-width: 900px;
  margin: 0 auto;
  padding: var(--edge);
}
#notYetNotice { max-width: var(--measure); margin: 2rem auto; text-align: center; }

.certificate {
  background: var(--card);
  padding: clamp(1.5rem, 4vw, 3rem);
}
.certificate__frame {
  position: relative;
  border: 1px solid var(--tape);
  padding: clamp(2rem, 6vw, 4rem) clamp(1.5rem, 5vw, 3.5rem);
  text-align: center;
}
.certificate__frame::before {
  /* A second, inset hairline - the classic double-rule certificate
     border, without needing two nested elements. */
  content: "";
  position: absolute;
  inset: 10px;
  border: 1px solid var(--hairline);
  pointer-events: none;
}
.certificate__corner {
  position: absolute;
  width: 28px;
  height: 28px;
  border: 2px solid var(--tape);
}
.certificate__corner--tl { top: -1px; left: -1px; border-right: none; border-bottom: none; }
.certificate__corner--tr { top: -1px; right: -1px; border-left: none; border-bottom: none; }
.certificate__corner--bl { bottom: -1px; left: -1px; border-right: none; border-top: none; }
.certificate__corner--br { bottom: -1px; right: -1px; border-left: none; border-top: none; }

.certificate__eyebrow {
  font-family: var(--mono);
  font-size: .6875rem;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--slate);
  margin: 0 0 .75rem;
}
.certificate__title {
  font-family: var(--serif);
  font-size: clamp(1.75rem, 4vw, 2.75rem);
  font-weight: 600;
  color: var(--ink);
  margin: 0;
}
.certificate__rule {
  width: 96px;
  height: 3px;
  background: var(--tape);
  margin: 1.25rem auto 1.75rem;
}
.certificate__lead {
  font-family: var(--sans);
  font-size: 1rem;
  color: var(--slate);
  margin: 0 0 .5rem;
}
.certificate__name {
  font-family: var(--serif);
  font-size: clamp(1.75rem, 5vw, 2.5rem);
  font-weight: 700;
  color: var(--ink);
  margin: 0 0 .35rem;
}
.certificate__org {
  font-family: var(--sans);
  font-size: 1.0625rem;
  color: var(--slate);
  margin: 0 0 1.75rem;
}
.certificate__org span { color: var(--ink); font-weight: 600; }
.certificate__body {
  max-width: 46ch;
  margin: 0 auto 2rem;
  font-family: var(--sans);
  line-height: 1.6;
  color: var(--ink);
}

.certificate__seal {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: .1rem;
  padding: 1.25rem 2rem;
  border: 1px solid var(--hairline);
  background: var(--concrete);
  margin: 0 auto 2rem;
}
.certificate__seal-emoji { font-size: 2.5rem; margin: 0 0 .25rem; }
.certificate__seal-label {
  font-family: var(--mono);
  font-size: .625rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--slate);
  margin: 0;
}
.certificate__seal-rank {
  font-family: var(--serif);
  font-size: 1.375rem;
  font-weight: 700;
  color: var(--tape-text);
  margin: .1rem 0 0;
}

.certificate__badges {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: .6rem;
  margin: 0 0 2.25rem;
}
.certificate__badge {
  position: relative;
  display: flex;
  align-items: center;
  gap: .4rem;
  padding: .35rem .75rem;
  border: 1px solid var(--hairline);
  border-radius: 999px;
  font-family: var(--sans);
  font-size: .8125rem;
  color: var(--ink);
  background: var(--card);
  cursor: pointer;
}
.certificate__badge-emoji { font-size: 1rem; }

/* Shown on hover AND keyboard focus - not a native title tooltip, which
   is mouse-hover-only and never reachable by keyboard at all. */
.certificate__badge-desc {
  position: absolute;
  bottom: 100%;
  left: 50%;
  transform: translateX(-50%);
  margin-bottom: .4rem;
  padding: .5rem .65rem;
  width: max-content;
  max-width: 220px;
  text-align: center;
  background: var(--ink);
  color: var(--card);
  font-size: .75rem;
  line-height: 1.35;
  border-radius: 2px;
  opacity: 0;
  pointer-events: none;
  transition: opacity .15s ease;
  z-index: 10;
}
.certificate__badge:hover .certificate__badge-desc,
.certificate__badge:focus-visible .certificate__badge-desc {
  opacity: 1;
}

.certificate__foot {
  display: flex;
  flex-wrap: wrap; /* was single-row only - overlapped/overflowed on very narrow phones */
  justify-content: space-between;
  align-items: flex-end;
  border-top: 1px solid var(--hairline);
  padding-top: 1.25rem;
  gap: 1rem;
}
.certificate__foot-col { text-align: left; }
.certificate__foot-col--seal { text-align: right; }
.certificate__date {
  font-family: var(--serif);
  font-size: 1.0625rem;
  font-weight: 600;
  color: var(--ink);
  margin: 0;
}
.certificate__stamp {
  font-family: var(--mono);
  font-size: 1rem;
  letter-spacing: .08em;
  color: var(--tape-text);
  margin: 0;
}
.certificate__foot-label {
  font-family: var(--mono);
  font-size: .625rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--slate);
  margin: .2rem 0 0;
}

@media print {
  /* Theme tokens, not hardcoded hex - a whitelabeled org's chosen colors
     (--concrete/--card/--tape are all overridable per-org, see
     src/superadmin.js's whitelabel editor) must survive printing the same
     way they already do on-screen, not fall back to a generic palette. */
  .cert-toolbar, .skip { display: none; }
  body.certificate-page { background: var(--concrete); }
  .cert-stage { max-width: none; padding: 0; }
  .certificate { background: var(--card); padding: 0; box-shadow: none; }
  .certificate__frame { border-color: var(--tape); }
  .certificate__frame::before { border-color: var(--hairline); }
  .certificate__corner { border-color: var(--tape); }
}

/* Paging control under an admin grid (src/pager.js) */
.admin-table tbody tr[hidden] { display: none; }
.grid-pager { display: flex; align-items: center; justify-content: flex-end; gap: .75rem; margin: .6rem 0 1rem; flex-wrap: wrap; }
.grid-pager[hidden] { display: none; }
.grid-pager__label { color: var(--slate); font-size: .9rem; font-variant-numeric: tabular-nums; }

/* SuperAdmin: course checklist, bulk edit, sign-in method and its impact notice */
.check { display: flex; gap: .55rem; align-items: flex-start; font-size: .9rem; margin-top: .4rem; }
.check input { margin-top: .25rem; }
.checklist { display: grid; gap: .35rem; max-height: 14rem; overflow-y: auto; border: 1px solid var(--hairline); border-radius: 8px; padding: .6rem .7rem; background: var(--card); }
.checklist__row { display: flex; gap: .55rem; align-items: flex-start; font-size: .92rem; cursor: pointer; }
.checklist__tools { display: flex; gap: .5rem; margin-top: .4rem; }
.choice { border: 0; padding: 0; margin: 0 0 .8rem; }
.choice__row { display: flex; gap: .7rem; align-items: flex-start; padding: .7rem .8rem; border: 1px solid var(--hairline); border-radius: 8px; margin-top: .5rem; cursor: pointer; background: var(--card); }
.choice__row:has(input:checked) { border-color: var(--verify); box-shadow: 0 0 0 1px var(--verify); }
.impact { display: grid; gap: .5rem; margin: .8rem 0; }
.impact__item { margin: 0; padding: .65rem .8rem; border-radius: 8px; border-left: 5px solid var(--hairline); background: var(--card); font-size: .92rem; }
.impact__item--critical { border-left-color: #B3261E; }
.impact__item--warning { border-left-color: #B26A00; }
.impact-banner { border: 2px solid #B3261E; border-radius: 10px; padding: 1.1rem 1.25rem; background: var(--card); margin-bottom: 1rem; }
.impact-banner__head { font-weight: 700; font-size: 1.15rem; margin: 0 0 .6rem; }
.impact-banner ul { margin: 0; padding-left: 1.2rem; display: grid; gap: .5rem; }
.modal__box--wide { width: min(640px, 100%); }
.btn--danger { background: #B3261E; color: #fff; border-color: #B3261E; }
.btn--danger:hover:not(:disabled) { filter: brightness(1.1); }
.btn--danger:disabled { opacity: .5; cursor: not-allowed; }

.table-scroll { overflow: auto; max-height: 18rem; border: 1px solid var(--hairline); border-radius: 8px; margin: .6rem 0; }
.modal__box textarea.input { font-family: var(--mono); font-size: .85rem; }

/* ---------- learner landing page: My training ---------- */
.training-home { margin-top: 1.5rem; max-width: 72rem; }
.training-home__head { display: flex; justify-content: space-between; gap: 1rem; align-items: flex-start; flex-wrap: wrap; margin-bottom: 1.2rem; }
.training-home__head h2 { margin-bottom: .2rem; }
.training-home__lead { color: var(--slate); margin: 0; }
.tcat { border: 1px solid var(--hairline); border-radius: 2px; background: var(--card); padding: 1.2rem 1.3rem; margin-bottom: 1.4rem; }
.tcat__title { font-family: var(--serif); font-size: 1.35rem; margin: 0 0 .8rem; padding-bottom: .5rem; border-bottom: 3px solid var(--tape); }
.tcat__sub { font-family: var(--mono); font-size: .75rem; letter-spacing: .1em; text-transform: uppercase; color: var(--slate); margin: 1rem 0 .6rem; }
.tcat__empty { color: var(--slate); margin: .3rem 0 1rem; }
.tgrid { display: grid; gap: .8rem; grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); }
.tcard { display: flex; flex-direction: column; gap: .4rem; align-items: flex-start; border: 1px solid var(--hairline); border-left: 4px solid var(--verify); border-radius: 2px; padding: .9rem 1rem; background: var(--bg); text-align: left; font: inherit; color: var(--ink); }
.tcard--overdue { border-left-color: #B3261E; }
.tcard--done { border-left-color: var(--hairline); }
.tcard__title { font-family: var(--serif); font-size: 1.05rem; margin: 0; }
.tcard__meta, .tcard__due { margin: 0; font-size: .88rem; color: var(--slate); }
.tcard--overdue .tcard__meta { color: #B3261E; font-weight: 600; }
.tcard .btn { margin-top: auto; }
.tcard--app { cursor: pointer; border-left-color: var(--tape); }
.tcard--app span { font-size: .88rem; color: var(--slate); }
.tfold { margin-top: .9rem; }
.tfold > summary { cursor: pointer; font-weight: 600; padding: .5rem 0; }
.tfold[open] > summary { margin-bottom: .5rem; }
.tyears__year { font-family: var(--mono); font-size: .8rem; letter-spacing: .08em; color: var(--slate); margin: .9rem 0 .4rem; }

/* The Beta Participant Terms page (server/beta/terms.js) */
.terms-page { max-width: 46rem; margin: 0 auto; padding: 2rem 1rem 3rem; }
.terms-page__body h1 { font-size: 1.5rem; margin: 0 0 1rem; text-wrap: balance; }
.terms-page__body p { line-height: 1.6; margin: .9rem 0; }
.terms-page__version { opacity: .7; font-size: .875rem; }
.terms-page__example { border-left: 4px solid #3f8f4f; background: rgba(63, 143, 79, .1); padding: .6rem .9rem; border-radius: 0 .25rem .25rem 0; }

/* ---------- the refresh (2026-10-20): within the brand ----------
   Same identity (concrete and signal yellow, the serif headings, mono labels), softer shape and clearer hierarchy: rounded cards, a pill for chips,
   a proper progress bar, sheet-style dialogs on a phone, a bottom action bar for Back and Next, safe areas for a notch, dynamic viewport height.
   Written as one layer after everything else so a theme or a page rule above can still be read on its own. System fonts only. */

html { scroll-padding-top: 6rem; }
body { min-height: 100vh; min-height: 100dvh; padding-bottom: env(safe-area-inset-bottom, 0px); }
.bar__inner, .track__inner, main { padding-left: max(var(--edge), env(safe-area-inset-left, 0px)); padding-right: max(var(--edge), env(safe-area-inset-right, 0px)); }
h1, h2, .module__title, .bar__title { text-wrap: balance; }
.module__title { font-size: clamp(1.5rem, 1.1rem + 2vw, 2.25rem); line-height: 1.15; }

/* shape and depth */
.panel, .quiz, .lesson__card, .auth__box, .certificate__frame, .feedback-item, .course-picker__option, .apps-panel__tile, .badge-shelf__item { border-radius: var(--radius); }
.panel, .quiz, .lesson__card, .auth__box { box-shadow: var(--shadow); }
.panel--action, .lesson__card, .auth__box { border-top-width: 3px; }
.btn { border-radius: var(--radius-sm); }
.btn--primary { box-shadow: var(--shadow); }
.input, .field select, select.input, textarea.input { border-radius: var(--radius-sm); min-height: 44px; }
.option { border-radius: 10px; padding: .8rem 1rem; background: var(--card); }
.option:has(input:checked) { background: var(--soft); }
.option input { width: 1.15rem; height: 1.15rem; }
.feedback { border-radius: var(--radius-sm); }
.feedback.is-right { background: var(--ok-bg); }
.cell { border-radius: var(--radius-sm); }
.tag { display: inline-block; }
.rank-chip, .badge-chip { border-radius: 999px; }
.meter { height: 6px; border-radius: 3px; background: var(--soft); }
.meter__fill { background: var(--tape); border-radius: 3px; }
.modal { background: rgba(10, 10, 12, .6); }
.modal__box { border-radius: 14px; border-top-width: 4px; box-shadow: 0 12px 40px rgba(0, 0, 0, .35); }
.table-wrap, .admin-table { border-radius: var(--radius-sm); }
.admin-table th { background: transparent; }
.admin-table td { border-bottom-color: var(--row); }
.stat-row .btn, .stat-row > * { border-radius: var(--radius); }
.training-home .panel, .course-picker__list > * { border-radius: var(--radius); }

/* the header: a quiet bar that holds its place */
.bar { box-shadow: 0 1px 0 var(--hairline); }
/* the logo files carry a white ground: on a dark theme give it a deliberate rounded tile instead of a stray white box */
:root[data-theme="dark"] .brand-logo { background: #fff; border-radius: 8px; padding: 3px 6px; }
.bar__tools { gap: .5rem; align-items: center; }

/* focus: the ink ring everywhere, with the brand yellow around it so it is seen on any surface */
:focus-visible { outline: 3px solid var(--ink); outline-offset: 2px; box-shadow: 0 0 0 6px var(--tape); border-radius: var(--radius-sm); }
input[type="radio"]:focus-visible, input[type="checkbox"]:focus-visible { box-shadow: 0 0 0 5px var(--tape); }

/* ---------- phones (a 6 to 7 inch screen is about 360 to 430 px wide): breakpoints 360, 600, 900, 1200 ---------- */

@media (max-width: 900px) {
  .bar__inner { gap: .6rem; }
  .bar__tools { width: 100%; justify-content: flex-start; }
  main { padding-top: 1.25rem; }
}

@media (max-width: 600px) {
  :root { --edge: 1rem; }
  .bar__title { font-size: 1.2rem; }
  .brand-logo--icon { height: 2rem; }
  .bar__tools .btn { padding: .8rem .9rem; min-height: 44px; }
  /* a compact header: the subtitle goes, and a Reset progress button that is disabled in a signed-in session does not take a row */
  .bar__sub { display: none; }
  .bar__brand { gap: .75rem; align-items: center; }
  #reset:disabled { display: none; }
  .bar__tools .field { flex: none; }
  /* the module strip: one scrolling row of tappable cells instead of a grid that wraps to three rows */
  .strip { display: flex; overflow-x: auto; gap: 6px; padding-bottom: .35rem; scroll-snap-type: x proximity; -webkit-overflow-scrolling: touch; scrollbar-width: thin; }
  .strip .cell { flex: 0 0 44px; scroll-snap-align: center; }
  /* Back and Next: a bar that stays at the bottom of the screen, above the notch's home indicator */
  .pager { position: sticky; bottom: 0; z-index: 25; background: var(--card); border-top: 1px solid var(--hairline); margin: 0 calc(var(--edge) * -1); padding: .75rem var(--edge) calc(.75rem + env(safe-area-inset-bottom, 0px)); box-shadow: 0 -4px 14px rgba(23, 24, 28, .08); }
  .pager .btn { flex: 1 1 0; text-align: center; min-height: 44px; }
  .pager__pos { display: none; }
  /* the lesson card's own Back and Next stack, the primary action first under the thumb */
  .lesson__nav { flex-direction: column-reverse; }
  .lesson__nav .btn, .lesson__nav .btn--primary, .lesson__nav .btn--quiet { width: 100%; min-width: 0; }
  .lesson__card { padding-right: clamp(1.1rem, 3vw, 1.75rem); }
  .quiz { padding: 1rem; margin: 1.25rem 0; }
  .quiz__actions { flex-direction: column; align-items: stretch; }
  .quiz__actions .btn { width: 100%; }
  /* dialogs become sheets that rise from the bottom edge */
  .modal { place-items: end center; padding: 0; }
  .modal__box, .modal__box--wide, .feedback-box { width: 100%; max-height: 92vh; max-height: 92dvh; border-radius: 16px 16px 0 0; padding-bottom: env(safe-area-inset-bottom, 0px); }
  .stat-row { gap: .5rem; }
  .stat-row > * { flex: 1 1 calc(50% - .5rem); }
  .auth { align-items: start; padding-top: 12vh; }
  .auth__box { box-shadow: none; }
}

@media (max-width: 360px) {
  .bar__tools .btn { padding: .8rem .7rem; font-size: .8125rem; }
  .module__title { font-size: 1.4rem; }
}

@media (min-width: 1200px) {
  .bar__inner, .track__inner, main { max-width: 1180px; }
}

/* ---------- the layout after the mockup (2026-10-20): the module list beside the page, a segmented bar on a tablet ---------- */

/* a tablet: the module strip is one row of segments; each segment is still a button 44 px tall (the segment is drawn inside it) */
@media (min-width: 601px) and (max-width: 1099px) {
  .strip { grid-template-columns: none; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: 3px; }
  .strip .cell { background: transparent; border-color: transparent; color: transparent; }
  .strip .cell:hover { border-color: transparent; }
  .strip .cell__num, .strip .cell__title { display: none; }
  .strip .cell::after { content: ""; position: absolute; left: 0; right: 0; top: 50%; height: 8px; margin-top: -4px; border-radius: 3px; background: var(--hairline); }
  .strip .cell.is-attempted::after { background: var(--signal); }
  .strip .cell.is-cleared::after { background: var(--verify); }
  .strip .cell.is-current::after { background: var(--tape); box-shadow: 0 0 0 2px var(--ink); }
  .strip .cell.is-current { border-width: 1px; }
  .strip .cell.is-locked { opacity: .55; }
}

/* a laptop: the progress block becomes a list of the modules beside the page, with the same buttons and handlers */
@media (min-width: 1100px) {
  body:has(.track:not([hidden])) { display: grid; grid-template-columns: minmax(var(--edge), 1fr) 250px 28px minmax(0, 902px) minmax(var(--edge), 1fr); align-content: start; }
  body:has(.track:not([hidden])) > * { grid-column: 1 / -1; }
  body:has(.track:not([hidden])) > .track { grid-column: 2; position: sticky; top: 16px; align-self: start; max-height: calc(100vh - 32px); max-height: calc(100dvh - 32px); overflow-y: auto; background: transparent; border: 0; margin-top: 2rem; z-index: 1; }
  body:has(.track:not([hidden])) > main { grid-column: 4; max-width: none; margin: 0; padding-left: 0; padding-right: 0; min-width: 0; }
  .track__inner { max-width: none; padding: 0 0 1rem; }
  .track__meta { flex-direction: column; align-items: flex-start; gap: .2rem; margin-bottom: .6rem; }
  .track__label .tag { letter-spacing: .09em; }
  .meter { margin-bottom: .9rem; }
  .strip { display: flex; flex-direction: column; gap: 2px; }
  .strip .cell { height: auto; min-height: 44px; display: flex; align-items: center; justify-content: flex-start; gap: .7rem; padding: .5rem .75rem; text-align: left; border: 0; border-left: 4px solid transparent; border-radius: var(--radius-sm); background: transparent; font-family: inherit; font-size: .9rem; color: var(--slate); }
  .strip .cell:hover { background: var(--soft); color: var(--ink); }
  .strip .cell__num { display: none; }
  .strip .cell__title { display: block; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .strip .cell::before { content: "\25CB"; width: 1.2rem; flex: none; text-align: center; font-size: .85rem; }
  .strip .cell.is-attempted { background: transparent; color: var(--slate); }
  .strip .cell.is-attempted::before { content: "\25D0"; color: var(--signal); }
  .strip .cell.is-cleared { background: transparent; border-color: transparent; color: var(--slate); }
  .strip .cell.is-cleared::before { content: "\2713"; color: var(--verify); font-weight: 700; }
  .strip .cell.is-locked { opacity: .55; }
  .strip .cell.is-locked::before { content: "\1F512"; font-size: .8rem; }
  .strip .cell.is-current, .strip .cell.is-current.is-cleared { background: var(--card); color: var(--ink); font-weight: 600; border-left-color: var(--tape); border-width: 0 0 0 4px; box-shadow: var(--shadow); }
  .strip .cell.is-current::before { content: "\25B6"; color: var(--ink); }
}

/* a laptop: the course name and the tools share one row (the subtitle is cut with an ellipsis instead of pushing the tools down) */
@media (min-width: 1100px) {
  .bar__brand > div { min-width: 0; }
  .bar__title { white-space: nowrap; }
  .bar__sub { max-width: 15rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
}

/* the step-by-step lesson reads as one card: the status line, the bar, the step and Back / Next all inside it (the one-page view keeps its own panels) */
.lesson:has(> .lesson__trail) { display: flex; flex-direction: column; background: var(--card); border: 1px solid var(--hairline); border-radius: var(--radius); box-shadow: var(--shadow); padding: clamp(1rem, 3vw, 1.5rem); }
.lesson:has(> .lesson__trail) > .lesson__top { order: 0; margin-bottom: .25rem; }
.lesson:has(> .lesson__trail) > .lesson__meter { order: 1; margin: .35rem 0 0; font-size: .6875rem; letter-spacing: .09em; text-transform: uppercase; }
.lesson:has(> .lesson__trail) > .lesson__trail { order: 2; margin: 0 0 .5rem; }
.lesson:has(> .lesson__trail) > .lesson__card, .lesson__probe .lesson__card { order: 3; background: transparent; border: 0; box-shadow: none; border-radius: 0; padding: .25rem 0 .5rem; }
.lesson:has(> .lesson__trail) > .lesson__card .lesson__num, .lesson__probe .lesson__num { display: none; }
.lesson:has(> .lesson__trail) > .lesson__nav { order: 4; margin-top: .5rem; }

/* the module list beside the page: no sideways scroll, and the module's name is already the highlighted row */
@media (min-width: 1100px) {
  body:has(.track:not([hidden])) > .track { overflow-x: hidden; }
  .track__module-name { display: none; }
}

/* the video: a rounded stage and a large yellow play button, as in the mockup */
.clip__frame { border-radius: 12px; }
.clip__play { color: #17181C; }
.clip__play svg { width: 76px; height: 76px; padding: 22px; background: var(--tape); box-shadow: 0 6px 22px rgba(0, 0, 0, .4); }
@media (max-width: 600px) { .clip__play svg { width: 60px; height: 60px; padding: 18px; } }

/* quiz answers as lettered choices (the input stays in the page, hidden from sight but still the focusable control) */
.question__options { counter-reset: opt; gap: .6rem; }
.option { position: relative; counter-increment: opt; align-items: center; }
.option input { position: absolute; opacity: 0; width: 1px; height: 1px; margin: 0; pointer-events: none; }
.option::before { content: counter(opt, upper-alpha); flex: none; width: 28px; height: 28px; display: grid; place-items: center; border: 1px solid var(--hairline); border-radius: 50%; background: var(--card); color: var(--slate); font: 500 .75rem/1 var(--mono); }
.option:has(input[type="checkbox"])::before { border-radius: 7px; }
.option:has(input:checked)::before { background: var(--ink); border-color: var(--ink); color: var(--card); }
.option:has(input[type="checkbox"]:checked)::before { content: "\2713"; }
.option:has(input:focus-visible) { outline: 3px solid var(--ink); outline-offset: 2px; box-shadow: 0 0 0 6px var(--tape); }

/* the module name inside a strip cell is shown only where the strip is a list (laptop width, above) */
.cell__title { display: none; }

/* sign-in and passkey pages: on a laptop the form sits beside a dark headline panel */
.auth__aside { display: none; }
@media (min-width: 900px) {
  .auth:has(> .auth__aside) { grid-template-columns: 1fr 1fr; padding: 0; max-width: none; margin: 0; place-items: stretch; }
  .auth__aside { display: flex; flex-direction: column; justify-content: flex-end; gap: .9rem; padding: clamp(2rem, 5vw, 4.5rem); background: var(--ink); color: var(--concrete); }
  .auth__eyebrow { font-family: var(--mono); font-size: .75rem; letter-spacing: .09em; text-transform: uppercase; opacity: .8; }
  .auth__eyebrow::before { content: ""; display: block; width: 2.5rem; height: 4px; margin-bottom: .9rem; background: var(--tape); border-radius: 2px; }
  .auth__headline { font-family: var(--serif); font-size: clamp(1.75rem, 3vw, 2.5rem); line-height: 1.15; font-weight: 500; text-wrap: balance; max-width: 18ch; }
  .auth:has(> .auth__aside) > .auth__box { place-self: center; width: min(420px, calc(100% - 4rem)); border: 0; border-top: 0; background: transparent; box-shadow: none; padding: 2rem 0; }
}

/* admin pages: small rounded labels, the section menu and the figures at the top (mockup) */
.chip { display: inline-block; padding: .25rem .6rem; border-radius: 999px; background: var(--warn-bg); color: var(--warn-text); font: 500 .75rem/1.2 var(--sans); white-space: nowrap; }
.chip--ok { background: var(--ok-bg); color: var(--verify); }
.chip--muted { background: var(--soft); color: var(--slate); }
.section-nav { display: flex; gap: .4rem; overflow-x: auto; margin: 0 0 1.25rem; padding-bottom: .25rem; scrollbar-width: thin; }
.section-nav a { flex: none; display: inline-flex; align-items: center; min-height: 44px; padding: 0 1rem; border-radius: var(--radius-sm); color: var(--slate); text-decoration: none; font-size: .9375rem; }
.section-nav a:hover { background: var(--soft); color: var(--ink); }
.section-nav a:first-child { background: var(--ink); color: var(--concrete); }
.section-nav a[hidden] { display: none; }
.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: .75rem; margin: 0 0 1.25rem; }
.tile { background: var(--card); border: 1px solid var(--hairline); border-radius: var(--radius); padding: .8rem 1rem; box-shadow: var(--shadow); }
.tile__label { display: block; font: 500 .6875rem/1.4 var(--mono); letter-spacing: .09em; text-transform: uppercase; color: var(--slate); }
.tile b { display: block; font: 500 1.5rem/1.3 var(--serif); }
@media (max-width: 600px) { .tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* SuperAdmin on a laptop: the section menu is a list beside the page */
@media (min-width: 1100px) {
  #adminContent:not([hidden]):has(> .section-nav--side) { display: grid; grid-template-columns: 210px minmax(0, 1fr); column-gap: 28px; align-items: start; }
  #adminContent:not([hidden]):has(> .section-nav--side) > * { grid-column: 2; }
  #adminContent:not([hidden]) > .section-nav--side { grid-column: 1; grid-row: 1 / span 30; position: sticky; top: 16px; flex-direction: column; overflow: visible; margin: 0; padding: 0; gap: 2px; }
  .section-nav--side a { min-height: 44px; border-left: 4px solid transparent; }
  .section-nav--side a:first-child { background: var(--card); color: var(--ink); border-left-color: var(--tape); box-shadow: var(--shadow); }
}

/* the page-not-found screen: one centred message and one way out */
.notfound { text-align: center; max-width: 30rem; display: flex; flex-direction: column; align-items: center; gap: .5rem; }
.notfound .brand-logo { margin-bottom: 1rem; }
.notfound__code { font: 500 .75rem/1.4 var(--mono); letter-spacing: .09em; text-transform: uppercase; color: var(--slate); }
.notfound__title { font-family: var(--serif); font-size: clamp(2rem, 6vw, 2.75rem); line-height: 1.1; font-weight: 500; text-wrap: balance; }
.notfound__text { color: var(--slate); max-width: 34ch; margin-bottom: .75rem; }

/* the certificate keeps the look it had before the refresh: its own colours (the palette of 2026-10-19), a square double-ruled frame */
body.certificate-page { --concrete: #E4E5E2; --card: #F7F7F5; --ink: #161A18; --slate: #5C6360; --hairline: #C7C9C4; --signal: #C2410C; --verify: #14594A; --tape-text: #7A5800; }
:root[data-theme="light"] body.certificate-page { --concrete: #FFFFFF; --card: #F3F4F5; --ink: #0A0C0B; --slate: #454B48; --hairline: #D4D7D3; --signal: #A83208; --verify: #0E4C3E; --tape-text: #A97600; }
:root[data-theme="dark"] body.certificate-page { --concrete: #13171A; --card: #1D2327; --ink: #EEF1F0; --slate: #AAB2AF; --hairline: #363E43; --signal: #FF8A5B; --verify: #46C6A6; --tape-text: #F0B429; }
body.certificate-page .certificate__frame { border-radius: 0; }

/* My Training after the mockup: flat sections, a count chip, white cards with a green edge, the status and date on one line */
.training-home__head h2 { font-size: clamp(1.75rem, 1.4rem + 1.5vw, 2.25rem); }
.tcat { border: 0; background: transparent; padding: 0; margin-bottom: 1.75rem; }
.tcat__head { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin: 0 0 .9rem; }
.tcat__head .tcat__title { border: 0; padding: 0; margin: 0; }
.tgrid { gap: .9rem; }
.tcard { gap: .5rem; padding: 1.1rem 1.25rem; border-radius: var(--radius); background: var(--card); box-shadow: var(--shadow); }
.tcard__title { font-size: 1.2rem; line-height: 1.3; }
.tcard__meta, .tcard__due { font-family: var(--mono); font-size: .75rem; letter-spacing: .02em; }
.training-home__head h2 { font-family: var(--serif); font-weight: 500; }
.tcard .btn { margin-top: .4rem; }
.tcard--done { box-shadow: none; }

/* a laptop, in a course: the header (course name, rank, badges, theme, My Training, Sign out) stays at the top of the window, and the module list sits below it */
@media (min-width: 1100px) {
  body:has(.track:not([hidden])) > .bar { position: sticky; top: 0; z-index: 30; }
  body:has(.track:not([hidden])) > .track { top: calc(var(--bar-h, 96px) + 16px); max-height: calc(100vh - var(--bar-h, 96px) - 32px); max-height: calc(100dvh - var(--bar-h, 96px) - 32px); }
  html:has(.track:not([hidden])) { scroll-padding-top: calc(var(--bar-h, 96px) + 12px); }
  .lesson, .quiz-area { scroll-margin-top: calc(var(--bar-h, 96px) + 12px); }
}

/* ---- My Training: the card that sends a learner to the Add-ons page (2026-10-21) ----
   The four add-on logos fan out on the left, the sentence is the link (its target covers the whole card), an arrow slides on hover.
   Phones stack the logos above the text. Colors come from the theme tokens, so it follows light and dark. */
.addons-nudge { position: relative; display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 1.2rem 1.6rem; margin: 2.2rem 0 1rem; padding: 1.2rem 1.6rem 1.2rem 1.3rem; border: 1px solid var(--hairline); border-radius: var(--radius); background:
  radial-gradient(120% 140% at 0% 0%, color-mix(in srgb, var(--tape) 20%, transparent), transparent 58%), var(--card); box-shadow: var(--shadow-sm); transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease; overflow: hidden; }
.addons-nudge:hover { box-shadow: var(--shadow); border-color: var(--tape); }
.addons-nudge:focus-within { outline: 3px solid var(--tape); outline-offset: 3px; }
.addons-nudge__logos { display: flex; align-items: center; padding-left: .6rem; }
.addons-nudge__logo { width: 4.4rem; height: 4.4rem; margin-left: -1.1rem; flex: none; transition: transform .25s ease; filter: drop-shadow(0 6px 8px rgba(23, 24, 28, .25)); }
.addons-nudge__logo:nth-child(1) { transform: rotate(-7deg); margin-left: 0; }
.addons-nudge__logo:nth-child(2) { transform: translateY(-4px) rotate(-2deg); }
.addons-nudge__logo:nth-child(3) { transform: translateY(2px) rotate(3deg); }
.addons-nudge__logo:nth-child(4) { transform: translateY(-3px) rotate(8deg); }
.addons-nudge__title { font-family: var(--serif); font-size: clamp(1.2rem, 1rem + .9vw, 1.6rem); line-height: 1.2; margin: 0 0 .3rem; }
.addons-nudge__link { color: var(--ink); text-decoration: underline; text-decoration-color: var(--tape); text-decoration-thickness: .22em; text-underline-offset: .16em; font-weight: 700; }
.addons-nudge__link::after { content: ""; position: absolute; inset: 0; border-radius: var(--radius); }
.addons-nudge__link:focus-visible { outline: none; }
.addons-nudge__lead { margin: 0; color: var(--slate); max-width: 60ch; }
.addons-nudge__arrow { display: grid; place-items: center; width: 2.75rem; height: 2.75rem; border-radius: 50%; background: var(--tape); color: var(--tape-ink); font-size: 1.3rem; font-weight: 700; transition: transform .2s ease; }
@media (max-width: 40rem) {
  .addons-nudge { grid-template-columns: minmax(0, 1fr) auto; padding: 1.1rem 1.1rem 1.2rem; }
  .addons-nudge__logos { grid-column: 1 / -1; justify-content: center; padding-left: 0; }
  .addons-nudge__logo { width: 3.6rem; height: 3.6rem; }
}
@media (prefers-reduced-motion: no-preference) {
  .addons-nudge:hover { transform: translateY(-2px); }
  .addons-nudge:hover .addons-nudge__logo:nth-child(1) { transform: translateX(-4px) rotate(-11deg); }
  .addons-nudge:hover .addons-nudge__logo:nth-child(2) { transform: translateY(-9px) rotate(-3deg); }
  .addons-nudge:hover .addons-nudge__logo:nth-child(3) { transform: translateY(-3px) rotate(5deg); }
  .addons-nudge:hover .addons-nudge__logo:nth-child(4) { transform: translateX(4px) translateY(-8px) rotate(12deg); }
  .addons-nudge:hover .addons-nudge__arrow { transform: translateX(5px); }
}
@media (prefers-reduced-motion: reduce) { .addons-nudge, .addons-nudge__logo, .addons-nudge__arrow { transition: none; } }
@media print { .addons-nudge { display: none; } }
