/*
 * Part-66 Trainer - application styles.
 *
 * Self-contained and namespaced under .p66 so it cannot leak into, or be
 * broken by, whatever theme surrounds it. Tokens mirror the p66-training
 * theme, but are redeclared here because the plugin must work under any theme.
 */

/* ------------------------------------------------------------------ *
 * IBM Plex Mono, served from this plugin.
 *
 * ⛔ SELF-HOSTED ON PURPOSE - do not swap this for a fonts.googleapis.com
 * link. Both themes on this account state that nothing about a visitor leaves
 * the server, and a CDN link would send every learner's IP to a third party
 * on every page view: the practice LG Munich I found unlawful in 2022
 * (3 O 17493/20). For a compliance product that is not a trade worth 30 KB.
 *
 * OFL 1.1 (Mike Abbink / Bold Monday / IBM), latin subset, the two weights
 * this file actually uses. To add a weight, fetch that subset and add a
 * matching @font-face - do not add a stylesheet link.
 *
 * font-display:swap so a slow font never blanks the questions.
 * ------------------------------------------------------------------ */
@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 400 700;          /* ONE variable file covers the whole range */
  font-display: swap;
  src: url("fonts/ibm-plex-sans-var.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/ibm-plex-mono-400.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("fonts/ibm-plex-mono-600.woff2") format("woff2");
}

/* ------------------------------------------------------------------ *
 * Plus Jakarta Sans - the reading face for the Signature theme.
 *
 * OFL 1.1 (Tokotype), v2.071, latin subset, ONE variable file covering
 * 200-800, 27 KB. Self-hosted for the same reason as the Plex faces: this
 * theme's own description promises no external requests of any kind.
 *
 * ⭐ CHOSEN FOR ITS FIGURES. It carries a real `tnum` feature, so scores,
 * marks and counts line up in columns without a monospace - which is the
 * whole point of the Signature theme, where nothing a learner reads is set
 * in mono.
 *
 * ⚠️ 229 codepoints, latin only. It has NO Greek and no maths symbols, so
 * π θ √ ∛ ∜ and the superscripts in the Module 1 bank fall through to the
 * stack below. IBM Plex Sans is exactly the same - this is not a
 * regression, it is a gap that predates both. See check-glyphs.py.
 * ------------------------------------------------------------------ */
@font-face {
  font-family: "Plus Jakarta Sans";
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url("fonts/plus-jakarta-sans-var.woff2") format("woff2");
}

.p66 {
  --g:  #0b0f14;  --pan: #121820; --pan2:#1a222c;
  --ink:#e7eef4;  --ink2:#a3b4c2; --ink3:#6f8496;
  --rule:#22303d; --ruleH:#34485a;
  --lime:#c3d24a; --amber:#ffb020; --cyan:#5cc8ff;
  --green:#3ddc84; --coral:#ff5c4d; --violet:#b48cff;
  --accInk:#0b0f14;
  /* Tint pairs, declared in the BASE so every theme has them. They were
     added for Signature only and referenced with a var() fallback, which
     meant seven themes silently drew no tint at all where one was intended. */
  --cyanBg: rgba(92,200,255,.12);
  --greenBg: rgba(61,220,132,.12);
  /* ⛔ SHAPE IS A TOKEN, NOT A LITERAL. Until 13 Sep 2026 a theme could
     only change colour: 28 of the 53 border-radius declarations in this
     file were hard-coded, so "instrument" and "blueprint" repainted an
     identically-shaped app and a learner could not tell them apart. All
     four now route through here. --rp is the pill, --rx the small stuff. */
  --r:14px; --rs:9px; --rp:999px; --rx:6px;
  /* ⛔ --fS NAMES NO WEBFONT, AND THAT IS DELIBERATE. It used to say
     "Barlow", pulled from Google Fonts - a face that was often not there, so
     the app fell back to Segoe UI and looked like every other study app on a
     Windows machine. Rather than ship a second webfont for prose, the design
     puts its character in the mono: in Technical Order every label, figure,
     module code and verdict is set in --fM. Prose is the system stack, which
     is what a manual's body text looks like anyway.
     ⚠️ If IBM Plex Sans is ever wanted here, self-host it beside the mono and
     add the @font-face above. Do NOT add a stylesheet link. */
  /* ⛔ --fS IS THE FACE EVERY WORD ON SCREEN IS SET IN, SO IT HAS TO BE OURS.
     It said "Barlow", pulled from Google Fonts, which frequently was not
     there - so the app fell back to Segoe UI, which is exactly why it looked
     like every other study app on a Windows machine.
     ⚠️ The first pass of the 13 Sep redesign self-hosted only the MONO and
     left this as a system stack, on the reasoning that the character could
     live in the labels. That was wrong, and was reported within the hour: the
     headings and the body - almost everything a learner actually reads - had
     not changed at all. The mono carries the labels; THIS carries the
     reading. Both have to be ours. Do NOT add a stylesheet link. */
  --fS:"IBM Plex Sans",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  --fM:"IBM Plex Mono",Consolas,"SF Mono",Menlo,"Courier New",monospace;

  /* ⛔ HOW A LABEL IS SET IS A TOKEN, NOT A LITERAL - the same lesson shape
     learned on 13 Sep 2026, in the same file, one layer up.

     On 13 Sep the aviation themes turned out to change only PAINT, because 28
     radii were hard-coded where no theme could reach them. Shape became
     --r/--rs/--rp/--rx and that was fixed. Typography had the identical fault
     and it was not spotted: 35 rule blocks across this file and the theme
     hard-coded the label face, its tracking, its weight and uppercase. A
     theme could recolour a label but never change how it was SET.

     That is the whole of the next report - "fonts still looking old and
     robotic", 13 Sep, with the webfonts verified loading on the live site.
     The face was never the problem. Sixty-odd labels in tracked-out uppercase
     mono is the problem, and no theme could have reached a single one.

     ⚠️ --fLabel and --fNum both default to the mono, so every theme that
     existed before this renders exactly as it did. The one deliberate change
     is --labelTrack: the file used SIX different values (.07 .1 .12 .13 .14
     .15em) for one idea, which is not a design, it is drift. */
  --fLabel: var(--fM);        /* small caps labels, eyebrows, verdicts   */
  --fNum:   var(--fM);        /* figures, scores, counts, tabular data   */
  --labelCase:   uppercase;
  --labelTrack:  .13em;
  --labelWeight: 700;

  background: var(--g);
  color: var(--ink);
  font-family: var(--fS);
  font-size: 17px;
  line-height: 1.55;
  border-radius: var(--r);
  padding: 26px;
  margin: 0 0 28px;
}

/* The app carries its own dark palette so it works under ANY theme, but when
   the surrounding site declares one of ours it should follow rather than sit
   there as a slab in the wrong colours. Same token names, different values -
   nothing downstream needs to know. */

:root[data-theme="daylight"] .p66,
:root[data-theme="light"] .p66 {
  --g:  #ffffff;  --pan: #f6f8fb; --pan2:#e8edf4;
  --ink:#101720;  --ink2:#43535f; --ink3:#6b7c8a;
  --rule:#d3dbe4; --ruleH:#adbbc8;
  --lime:#5c6b12; --amber:#9a6100; --cyan:#10607f;
  --green:#1c6b3c; --coral:#b03323; --violet:#6b46c1;
  --accInk:#ffffff;
  box-shadow: 0 1px 2px rgba(16,23,32,.06), 0 10px 30px rgba(16,23,32,.08);
}

:root[data-theme="workshop"] .p66 {
  --g:  #fbfcf8;  --pan: #ffffff; --pan2:#e2e6da;
  --ink:#191d17;  --ink2:#474e44; --ink3:#6e766a;
  --rule:#cfd4c6; --ruleH:#a9b09e;
  --lime:#4a5610; --amber:#8a5a12; --cyan:#2d4d5c;
  --green:#2f6b3a; --coral:#8a3a22; --violet:#6a4bb8;
  --accInk:#ffffff;
  --r:2px; --rs:2px; --rp:2px; --rx:2px;
  box-shadow: 0 1px 2px rgba(25,29,23,.08);
}

:root[data-theme="blueprint"] .p66 {
  --g:  #f7fafd;  --pan: #ffffff; --pan2:#d7e3ef;
  --ink:#12283d;  --ink2:#3c5871; --ink3:#6b829a;
  --rule:#b9cddf; --ruleH:#8fa9c2;
  --lime:#0f5c8c; --amber:#9a5b00; --cyan:#0f5c8c;
  --green:#16694a; --coral:#a8362a; --violet:#6b46c1;
  --accInk:#ffffff;
  --r:2px; --rs:2px; --rp:2px; --rx:2px;
  box-shadow: 0 1px 2px rgba(18,40,61,.10);
}

:root[data-theme="instrument"] .p66 {
  --g:  #000000;  --pan: #12171c; --pan2:#1c232a;
  --ink:#dfe6ea;  --ink2:#9fb0ba; --ink3:#71838e;
  --rule:#28313a; --ruleH:#3c4954;
  --lime:#ffb020; --amber:#ffb020; --cyan:#5cc8ff;
  --green:#3ddc84; --coral:#ff5c4d; --violet:#b48cff;
  --accInk:#0d1013;
  --r:4px; --rs:3px; --rp:3px; --rx:3px;
}

/* ------------------------------------------------------------------ *
 * TECHNICAL ORDER - the default since 13 September 2026.
 *
 * James: "the look and style of the app looks very same to the Spanna app on
 * the app store." He was right, and it was measurable rather than a matter of
 * taste: rounded cards, a gradient strip on every card, pill badges and a
 * hover lift are the parts bin every study app ships from.
 *
 * So this one is set like the maintenance manual he reads all day. Paper and
 * ink, hairline rules, zero radius, nothing floating. It is deliberately not
 * trying to be liked - a manual is not.
 *
 * ⛔ IT CHANGES SHAPE, NOT JUST PAINT. That is the whole difference between
 * this and the "instrument"/"blueprint" themes above, which only ever swapped
 * six colours. See the --rp/--rx note in the base block.
 *
 * ⛔ COLOUR STILL NEVER CARRIES MEANING ALONE. green/amber/coral keep their
 * jobs and every verdict is printed in words beside them - see the note over
 * composition_states() in class-shortcode.php for why that is not negotiable.
 * ------------------------------------------------------------------ */

/* ==================================================================== *
 * SIGNATURE - the premium look, and the default since 13 Sep 2026.
 *
 * James, 13 Sep, on Technical Order: "fonts still looking old and robotic",
 * "prefers the rounded boxes in the sections - the tiles", "likes the icons
 * but they need to feel more premium".
 *
 * ⛔ THE FONTS WERE LOADING. Verified on the live site before changing
 * anything: document.fonts reported IBM Plex Sans and IBM Plex Mono both
 * `loaded`, and all four woff2 files returned 200, byte-identical to local.
 * Chasing delivery again would have been the FOURTH consecutive time the
 * wrong thing was fixed here - see the module-marks note in HANDOVER.md,
 * where the same complaint was reported four times while fonts, caches and
 * themes were fixed instead of the thing being complained about.
 *
 * What was actually wrong was the SETTING, and no theme could reach it:
 *   - every corner squared off        --r/--rs/--rp/--rx all 0px
 *   - 35 labels in tracked-out mono   hard-coded in 35 rule blocks
 *   - every figure in a typewriter    because no tabular face was loaded
 *
 * So Signature is not a repaint. It changes the three things a theme
 * previously could not touch: the reading face, how a label is set, and
 * the shape of a tile.
 *
 * ⚠️ Technical Order is untouched and stays in the picker. A learner who
 * prefers the manual-on-paper look keeps it - that is what the picker is
 * for, and it is why the old looks were never deleted.
 * ==================================================================== */
:root[data-theme="signature"] .p66 {
  /* Neutrals carry the page; ONE saturated hue carries emphasis. Green,
     amber and coral stay reserved for verdicts - they are the only colours
     on this screen that MEAN anything, and spending them on decoration is
     part of what made the app read as generic. */
  --g:  #fbfbfd;  --pan: #ffffff; --pan2:#f2f3f7;
  --ink:#14161c;  --ink2:#4b5060; --ink3:#767c8c;
  --rule:#e8eaf0; --ruleH:#d2d6e0;
  --cyan:#4338ca;                       /* the one hue - indigo on white */
  --lime:#4a5510; --amber:#8a5200; --green:#12694a; --coral:#b3261e;
  --violet:#6d28d9;
  --accInk:#ffffff;
  /* Tint pairs. Declared HERE and not borrowed from the theme: the plugin has
     to render correctly under any theme at all, which is the reason this file
     redeclares every token rather than importing one. */
  --cyanBg: rgba(67,56,202,.09);
  --greenBg: rgba(18,105,74,.10);

  /* Rounded, and generous. Tiles, not boxes. */
  --r:18px; --rs:13px; --rp:999px; --rx:9px;

  /* ⭐ NOTHING A LEARNER READS IS SET IN MONO. The label face IS the
     reading face; what changes is weight and size, not family. Figures use
     the same face with its `tnum` feature, so a column of scores still
     lines up without a typewriter. */
  --fS:"Plus Jakarta Sans",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  --fLabel: var(--fS);
  --fNum:   var(--fS);
  --labelCase:   none;                  /* sentence case - CAPS IS THE ROBOT */
  --labelTrack:  .01em;
  --labelWeight: 600;

  border: 0;
  box-shadow: 0 1px 2px rgba(20,22,28,.04), 0 8px 24px -8px rgba(20,22,28,.10);
  font-variant-numeric: tabular-nums;
}

/* Headings do the job the tracked-out uppercase used to do, with weight and
   size instead of caps and spacing. */
:root[data-theme="signature"] .p66 h2,
:root[data-theme="signature"] .p66 h3,
:root[data-theme="signature"] .p66 h4 { font-weight: 800; letter-spacing: -.021em; }
:root[data-theme="signature"] .p66 .p66-eyebrow {
  font-size: .78rem; color: var(--ink3); font-weight: 600;
}

/* ⭐ TILES, NOT BOXES. The lift is what says "this is a surface" now that
   nothing is ruled off. */
:root[data-theme="signature"] .p66 .p66-card {
  border: 1px solid var(--rule);
  box-shadow: 0 1px 2px rgba(20,22,28,.04), 0 2px 8px -4px rgba(20,22,28,.06);
}
:root[data-theme="signature"] .p66 .p66-launch-card {
  border: 1px solid var(--rule);
  box-shadow: 0 1px 2px rgba(20,22,28,.04), 0 4px 14px -6px rgba(20,22,28,.08);
  transition: box-shadow .18s ease, border-color .18s ease, transform .18s ease;
}
:root[data-theme="signature"] .p66 .p66-launch-card::before { display: none; }
:root[data-theme="signature"] .p66 a.p66-launch-card:hover {
  transform: translateY(-2px); border-color: var(--ruleH);
  box-shadow: 0 2px 4px rgba(20,22,28,.05), 0 14px 30px -10px rgba(20,22,28,.16);
}

:root[data-theme="signature"] .p66 .p66-btn { font-weight: 600; letter-spacing: 0; }
:root[data-theme="signature"] .p66 .p66-btn-primary {
  background: var(--cyan); border-color: var(--cyan); color: #fff;
}
:root[data-theme="signature"] .p66 .p66-btn-primary:hover:not(:disabled) { filter: brightness(1.1); }

/* Verdicts read as soft status pills rather than stamped tags. Colour still
   never carries meaning alone - every one of these prints its word. */
:root[data-theme="signature"] .p66 .p66-prog-verdict,
:root[data-theme="signature"] .p66 .p66-launch-verdict,
:root[data-theme="signature"] .p66 .p66-pill { font-weight: 600; border: 0; padding: 4px 11px; }

/* ⭐ THE MODULE MARKS, MOUNTED.
 *
 * "likes the icons but they need to feel more premium" - 13 Sep 2026. The
 * drawings were not the problem and are not redrawn here: a radical, a
 * resistor, a hex fastener are the right marks and a Part-66 candidate reads
 * them without a caption. What was missing is that they were bare strokes
 * floating on the card in --ink3, the same grey as the small print, so they
 * read as clip-art dropped on a tile rather than as part of it.
 *
 * So each one gets MOUNTED: a soft tinted plate in the accent hue, the mark
 * in the accent itself, the plate's radius one step down from the card it
 * sits on. That last detail is the whole trick - nested radii that agree are
 * most of what separates a considered interface from an assembled one.
 *
 * ⛔ No change to P66_Marks and no change to the SVG. One table, three
 * consumers; this is presentation and it belongs in the theme that wants it.
 * The other six themes keep the bare stroke. */
:root[data-theme="signature"] .p66 .p66-launch-mk {
  width: 22px; height: 22px; padding: 9px; box-sizing: content-box;
  color: var(--cyan);
  background: var(--cyanBg);
  border: 1px solid var(--rule);
  border-radius: var(--rs);
  margin-bottom: 13px;
  transition: background .18s ease, color .18s ease, border-color .18s ease;
}
:root[data-theme="signature"] .p66 a.p66-launch-card:hover .p66-launch-mk {
  background: var(--cyan); color: var(--accInk); border-color: var(--cyan);
}
/* A module already at the pass mark says so in its mark as well as its
   verdict - green here is the same green it means everywhere else. */
:root[data-theme="signature"] .p66 .p66-launch-card .p66-launch-mk.ready {
  color: var(--green); background: var(--greenBg);
}
:root[data-theme="signature"] .p66 a.p66-launch-card:hover .p66-launch-mk.ready {
  background: var(--green); color: var(--accInk); border-color: var(--green);
}
/* In the ranked table the mark is an identifier, not a feature - it takes the
   accent but not the plate, or twenty of them would fight the bars. */
:root[data-theme="signature"] .p66 .p66-prog-mk { color: var(--cyan); opacity: .85; }
:root[data-theme="signature"] .p66 .p66-mk * { stroke-width: 1.7; }

/* Dark. The same design at night, not a different one. */
@media (prefers-color-scheme: dark) {
  :root[data-theme="signature"] .p66 {
    --g:  #0e0f14;  --pan: #16181f; --pan2:#1e212a;
    --ink:#eceef4;  --ink2:#a6abbb; --ink3:#787f90;
    --rule:#252936; --ruleH:#39404f;
    --cyan:#a5b4fc;
    --lime:#c3d24a; --amber:#ffb020; --green:#3ddc84; --coral:#ff6a53;
    --violet:#c4b5fd;
    --accInk:#0e0f14;
    --cyanBg: rgba(165,180,252,.13);
    --greenBg: rgba(61,220,132,.13);
    box-shadow: 0 1px 2px rgba(0,0,0,.4), 0 8px 24px -8px rgba(0,0,0,.5);
  }
  :root[data-theme="signature"] .p66 .p66-card,
  :root[data-theme="signature"] .p66 .p66-launch-card {
    box-shadow: 0 1px 2px rgba(0,0,0,.34), 0 4px 14px -6px rgba(0,0,0,.42);
  }
  :root[data-theme="signature"] .p66 a.p66-launch-card:hover {
    box-shadow: 0 2px 4px rgba(0,0,0,.4), 0 14px 30px -10px rgba(0,0,0,.55);
  }
  :root[data-theme="signature"] .p66 .p66-btn-primary { color: #0e0f14; }
}

:root[data-theme="technical"] .p66 {
  --g:  #fcfcfa;  --pan: #f7f7f4; --pan2:#eeeeea;
  --ink:#14171a;  --ink2:#4a5158; --ink3:#787f86;
  --rule:#c8ccc5; --ruleH:#9aa096;
  --lime:#4a5510; --amber:#7d5100; --cyan:#155e73;
  --green:#1c6238; --coral:#a8330f; --violet:#5b3fa8;
  --accInk:#fcfcfa;
  --r:0px; --rs:0px; --rp:0px; --rx:0px;
  box-shadow: none;
  border: 1px solid var(--rule);
}

/* No gradients anywhere. The strip across the top of every card was the single
   most template-looking thing in the file; here the card is ruled instead. */
:root[data-theme="technical"] .p66 .p66-launch-card::before { display: none; }
:root[data-theme="technical"] .p66 .p66-launch-card { border-top: 2px solid var(--ink); }
:root[data-theme="technical"] .p66 .p66-btn-primary {
  background: var(--ink); color: var(--g); border-color: var(--ink);
}
:root[data-theme="technical"] .p66 .p66-btn:hover:not(:disabled) { transform: none; filter: none; }
:root[data-theme="technical"] .p66 .p66-btn-primary:hover:not(:disabled) { background: var(--coral); border-color: var(--coral); }

/* Nothing lifts off the page. A row of cards that all rise on hover is motion
   spent saying "this is clickable", which the cursor already said. */
:root[data-theme="technical"] .p66 a.p66-launch-card:hover {
  transform: none; border-color: var(--ink); background: var(--pan2);
}

/* Verdict chips become tags: a rule and a word, not a coloured lozenge. */
:root[data-theme="technical"] .p66 .p66-prog-verdict,
:root[data-theme="technical"] .p66 .p66-launch-verdict {
  background: none; border: 1px solid currentColor; font-weight: 600;
}

/* Dark. A manual read at night, not a different design. */
@media (prefers-color-scheme: dark) {
  :root[data-theme="technical"] .p66 {
    --g:  #14171a;  --pan: #1b1f23; --pan2:#242a2f;
    --ink:#e8eae7;  --ink2:#a7b0b5; --ink3:#78838a;
    --rule:#333a3f; --ruleH:#4c565c;
    --lime:#b9c95a; --amber:#ffb020; --cyan:#5cc8ff;
    --green:#3ddc84; --coral:#ff6a53; --violet:#b48cff;
    --accInk:#14171a;
    border-color: var(--rule);
  }
  :root[data-theme="technical"] .p66 .p66-btn-primary { background: var(--ink); color: var(--g); border-color: var(--ink); }
  :root[data-theme="technical"] .p66 .p66-launch-card { border-top-color: var(--ruleH); }
}

/* Auto: follow the machine. Dark is already the default above. */
@media (prefers-color-scheme: light) {
  :root[data-theme="auto"] .p66 {
    --g:  #ffffff;  --pan: #f6f8fb; --pan2:#e8edf4;
    --ink:#101720;  --ink2:#43535f; --ink3:#6b7c8a;
    --rule:#d3dbe4; --ruleH:#adbbc8;
    --lime:#5c6b12; --amber:#9a6100; --cyan:#10607f;
    --green:#1c6b3c; --coral:#b03323; --violet:#6b46c1;
    --accInk:#ffffff;
    box-shadow: 0 1px 2px rgba(16,23,32,.06), 0 10px 30px rgba(16,23,32,.08);
  }
}

.p66 *, .p66 *::before, .p66 *::after { box-sizing: border-box; }
.p66 h2 { font-size: 1.7rem; font-weight: 800; letter-spacing: -.02em; margin: 0 0 .4em; line-height: 1.15; }
.p66 h3 { font-size: 1.12rem; font-weight: 700; margin: 0 0 .4em; }
.p66 p  { margin: 0 0 1em; }
.p66 a  { color: var(--cyan); }
.p66-muted { color: var(--ink2); }
.p66-small { font-size: .86rem; }
.p66-mono  { font-family: var(--fNum); }
.p66-hide  { display: none !important; }

.p66-loading { color: var(--ink3); font-family: var(--fLabel); font-size: .9rem; padding: 30px 0; }

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

.p66-btn {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 11px 20px; border-radius: var(--rx); border: 1px solid transparent;
  font: inherit; font-size: .94rem; font-weight: 700; text-decoration: none;
  cursor: pointer; transition: transform .12s ease, filter .12s ease;
}
.p66-btn:hover:not(:disabled) { transform: translateY(-1px); }
.p66-btn:disabled { opacity: .5; cursor: default; }
.p66-btn-primary { background: linear-gradient(135deg,var(--lime),var(--green)); color: var(--accInk); }
.p66-btn-ghost   { background: var(--pan); color: var(--ink); border-color: var(--rule); }
.p66-btn-ghost:hover { border-color: var(--ruleH); }
.p66-btn-sm { padding: 6px 13px; font-size: .82rem; border-radius: var(--rx); }

.p66 :focus-visible { outline: 3px solid var(--amber); outline-offset: 2px; border-radius: var(--rx); }

/* --------------------------------------------------------------- cards */

.p66-card { background: var(--pan); border: 1px solid var(--rule); border-radius: var(--r); padding: 22px; }
.p66-grid { display: grid; gap: 16px; }
.p66-g3 { grid-template-columns: repeat(3,1fr); }
.p66-g2 { grid-template-columns: 1.1fr .9fr; }
@media (max-width: 820px) { .p66-g3, .p66-g2 { grid-template-columns: 1fr; } }

.p66-eyebrow {
  font-family: var(--fLabel); font-size: .7rem; font-weight: var(--labelWeight); letter-spacing: var(--labelTrack);
  text-transform: var(--labelCase); color: var(--amber); margin: 0 0 10px;
}

/* ------------------------------------------------------------ dashboard */

.p66-head { display: flex; flex-wrap: wrap; gap: 14px; align-items: baseline; margin-bottom: 20px; }
.p66-head h2 { margin: 0; }
.p66-access {
  margin-left: auto; font-family: var(--fLabel); font-size: .76rem; font-weight: 700;
  padding: 6px 12px; border-radius: var(--rp); background: var(--pan2); color: var(--ink2);
}
.p66-access.warn { background: rgba(255,176,32,.14); color: var(--amber); }

.p66-dial { display: grid; place-items: center; gap: 10px; text-align: center; }
.p66-dial svg { width: 190px; height: 190px; transform: rotate(-90deg); }
.p66-dial .trk { fill: none; stroke: var(--rule); stroke-width: 13; }
.p66-dial .fil { fill: none; stroke-width: 13; stroke-linecap: round; transition: stroke-dashoffset .6s cubic-bezier(.22,1,.36,1); }
.p66-dialwrap { position: relative; }
.p66-dialnum {
  position: absolute; inset: 0; display: grid; place-content: center; gap: 2px;
}
.p66-dialnum b { font-size: 2.9rem; font-weight: 800; line-height: 1; font-variant-numeric: tabular-nums; }
.p66-dialnum span { font-family: var(--fLabel); font-size: .62rem; letter-spacing: var(--labelTrack); text-transform: var(--labelCase); color: var(--ink3); }

.p66-verdict {
  font-family: var(--fLabel); font-weight: var(--labelWeight); font-size: .76rem; letter-spacing: var(--labelTrack);
  text-transform: var(--labelCase); padding: 7px 15px; border-radius: var(--rp);
}
.p66-verdict.not_ready { background: rgba(255,92,77,.14); color: var(--coral); }
.p66-verdict.almost    { background: rgba(255,176,32,.14); color: var(--amber); }
.p66-verdict.ready     { background: rgba(61,220,132,.14); color: var(--green); }
/* Every multiple-choice condition met, but the paper also carries an essay
   this trainer cannot assess. Amber on purpose - it must never read green. */
.p66-verdict.ready_mcq { background: rgba(255,176,32,.14); color: var(--amber); }

.p66-next {
  border-left: 3px solid var(--lime); background: rgba(195,210,74,.08);
  border-radius: var(--rs); padding: 16px 18px; margin-bottom: 18px;
}
.p66-next h3 { margin-bottom: 4px; }

.p66-blockers { list-style: none; margin: 0; padding: 0; display: grid; gap: 9px; }
.p66-blockers li {
  display: flex; gap: 12px; align-items: center; flex-wrap: wrap;
  background: rgba(255,92,77,.09); border-left: 3px solid var(--coral);
  border-radius: var(--rs); padding: 12px 15px; font-size: .92rem;
}
.p66-blockers li.ok { background: rgba(61,220,132,.09); border-left-color: var(--green); }
.p66-blockers li .p66-btn { margin-left: auto; }
/* A caveat carries no action, because nothing the learner does here can
   clear it. Styled distinctly so it is not mistaken for a blocker. */
.p66-caveats li.caveat {
	background: rgba(255,176,32,.09);
	border-left-color: var(--amber);
}

.p66-stats { display: flex; flex-wrap: wrap; gap: 22px; margin: 4px 0 18px; }
.p66-stat .k { font-family: var(--fLabel); font-size: .64rem; letter-spacing: var(--labelTrack); text-transform: var(--labelCase); color: var(--ink3); }
.p66-stat .v { font-size: 1.5rem; font-weight: 800; line-height: 1.1; font-variant-numeric: tabular-nums; }

/* ---------------------------------------------------------- topic table */

.p66-topics { width: 100%; border-collapse: collapse; font-size: .9rem; }
.p66-topics th {
  text-align: left; font-family: var(--fLabel); font-size: .64rem; letter-spacing: var(--labelTrack);
  text-transform: var(--labelCase); color: var(--ink3); font-weight: var(--labelWeight);
  padding: 0 10px 8px; border-bottom: 1px solid var(--rule);
}
.p66-topics td { padding: 10px; border-bottom: 1px solid var(--rule); vertical-align: middle; }
.p66-topics tr:last-child td { border-bottom: 0; }
.p66-topics .num { font-family: var(--fNum); font-variant-numeric: tabular-nums; text-align: right; }
.p66-bar { height: 7px; border-radius: var(--rx); background: var(--pan2); overflow: hidden; min-width: 70px; }
.p66-bar i { display: block; height: 100%; border-radius: var(--rx); background: var(--green); }
.p66-bar i.mid { background: var(--amber); }
.p66-bar i.bad { background: var(--coral); }
.p66-bar i.none { background: var(--rule); }

/* ------------------------------------------------------------- question */

.p66-qtop {
  display: flex; flex-wrap: wrap; gap: 12px; align-items: center;
  padding-bottom: 14px; border-bottom: 1px solid var(--rule); margin-bottom: 20px;
}
.p66-topic {
  font-family: var(--fLabel); font-size: .7rem; font-weight: var(--labelWeight); letter-spacing: var(--labelTrack);
  text-transform: var(--labelCase); color: var(--cyan); background: rgba(92,200,255,.12);
  padding: 4px 10px; border-radius: var(--rp);
}
.p66-count { font-family: var(--fNum); font-size: .78rem; color: var(--ink3); }
.p66-clock {
  margin-left: auto; font-family: var(--fNum); font-size: 1.25rem; font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.p66-clock.low { color: var(--coral); }

.p66-stem { font-size: 1.18rem; font-weight: 700; line-height: 1.4; margin: 0 0 20px; }

.p66-opts { display: grid; gap: 10px; }
.p66-opt {
  display: flex; align-items: flex-start; gap: 13px; width: 100%; text-align: left;
  padding: 14px 16px; border-radius: var(--rs); border: 1.5px solid var(--rule);
  background: var(--g); color: var(--ink); font: inherit; font-size: .97rem; cursor: pointer;
  transition: border-color .12s ease, background .12s ease, transform .1s ease;
}
.p66-opt:hover:not(:disabled) { border-color: var(--ruleH); transform: translateX(3px); }
.p66-opt:disabled { cursor: default; }
.p66-opt .l {
  flex: none; width: 26px; height: 26px; border-radius: var(--rx); display: grid; place-items: center;
  font-family: var(--fLabel); font-weight: 700; font-size: .8rem; background: var(--pan2); color: var(--ink2);
}
.p66-opt.picked { border-color: var(--cyan); background: rgba(92,200,255,.10); }
.p66-opt.picked .l { background: var(--cyan); color: var(--accInk); }
/* Chosen, but the server has not graded it yet. Deliberately NOT a hue:
   any colour here reads as a verdict, and the learner then sees the option
   change colour twice before it settles. Neutral border, and the letter chip
   breathes so the click is visibly acknowledged. */
.p66-opt.pending { border-color: var(--ruleH); }
.p66-opt.pending .l { animation: p66pulse 1s ease-in-out infinite; }

@keyframes p66pulse { 0%,100% { opacity: 1; } 50% { opacity: .45; } }

@media (prefers-reduced-motion: reduce) {
  .p66-opt.pending .l { animation: none; opacity: .6; }
}

.p66-opt.right { border-color: var(--green); background: rgba(61,220,132,.11); }
.p66-opt.right .l { background: var(--green); color: var(--accInk); }
.p66-opt.wrong { border-color: var(--coral); background: rgba(255,92,77,.11); }
.p66-opt.wrong .l { background: var(--coral); color: #fff; }

.p66-fb { margin-top: 18px; display: grid; gap: 11px; }
.p66-fb div { border-left: 3px solid var(--rule); padding: 3px 0 3px 14px; }
.p66-fb .k {
  display: block; font-family: var(--fLabel); font-size: .62rem; font-weight: var(--labelWeight);
  letter-spacing: var(--labelTrack); text-transform: var(--labelCase); color: var(--ink3); margin-bottom: 3px;
}
.p66-fb .why  { border-color: var(--cyan); }
.p66-fb .tip  { border-color: var(--lime); }
.p66-fb .trap { border-color: var(--amber); }
.p66-fb p { margin: 0; font-size: .93rem; color: var(--ink2); }

/* ------------------------------------------------------------------ *
 * AMM CALLOUTS - Technical Order only.
 *
 * In a maintenance manual a CAUTION is not a coloured left border. It is the
 * word, centred, in caps, over a ruled box containing the text. That shape is
 * standardised and every engineer reads it without thinking: the box means
 * stop, the word tells you how hard.
 *
 * ⭐ This is the one piece of the redesign a competitor cannot copy quickly.
 * It only works because the bank already carries a tip AND a trap on all
 * 11,408 questions - the convention is worthless without something true to
 * put in it. See the note over the label list in trainer.js.
 *
 * ⛔ Scoped to [data-theme="technical"]. Every other theme keeps the left-rule
 * treatment, so a learner who switches back gets exactly what they had.
 * ------------------------------------------------------------------ */

:root[data-theme="technical"] .p66-fb { gap: 16px; }

:root[data-theme="technical"] .p66-fb .tip,
:root[data-theme="technical"] .p66-fb .trap {
  border: 1px solid var(--ink);
  border-left-width: 1px;
  padding: 16px 16px 14px;
  margin-top: 8px;
  position: relative;
  background: none;
}

/* The word sits ON the top rule, centred, with the rule broken around it -
   which is how it is set on paper. */
:root[data-theme="technical"] .p66-fb .tip .k,
:root[data-theme="technical"] .p66-fb .trap .k {
  position: absolute;
  top: 0;
  left: 50%;
  transform: translate(-50%, -50%);
  background: var(--pan);
  padding: 0 10px;
  margin: 0;
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .26em;   /* wide tracking - it is a placard, not a word */
  text-indent: .26em;      /* ⚠️ balances the trailing letter-space, or the
                              centring is off by half a space at this tracking */
}
:root[data-theme="technical"] .p66-fb .trap .k { color: var(--coral); }
:root[data-theme="technical"] .p66-fb .trap { border-color: var(--coral); }
:root[data-theme="technical"] .p66-fb .tip  .k { color: var(--ink); }
:root[data-theme="technical"] .p66-fb .tip  { border-color: var(--ruleH); }

:root[data-theme="technical"] .p66-fb .tip p,
:root[data-theme="technical"] .p66-fb .trap p { color: var(--ink); }

/* The answer itself is body text, not a callout - a manual does not box its
   own procedure. It keeps a single rule to mark it as the consequence. */
:root[data-theme="technical"] .p66-fb .why {
  border-left: 2px solid var(--ink); padding-left: 15px;
}

/* ⚠️ THE LABEL KNOCKS A HOLE IN ITS OWN BORDER, so its background must be
   whatever is actually behind it - get that wrong and the rule draws straight
   through the word. --pan is correct because feedback() only ever appends
   .p66-fb to a .p66-card (trainer.js:962), and .p66-card is --pan. Checked,
   not assumed. If the feedback is ever rendered anywhere else, this needs a
   matching value there or the callouts will look broken in that one place. */

.p66-qfoot {
  display: flex; flex-wrap: wrap; gap: 10px; align-items: center;
  padding-top: 18px; margin-top: 20px; border-top: 1px solid var(--rule);
}
.p66-qfoot .sp { margin-left: auto; }

.p66-nav { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 18px; }
.p66-nav button {
  width: 32px; height: 28px; border-radius: var(--rx); border: 1px solid var(--rule);
  background: var(--pan); color: var(--ink3); font-family: var(--fNum); font-size: .72rem;
  font-weight: 700; cursor: pointer;
}
.p66-nav button.done { background: var(--pan2); color: var(--ink); }
.p66-nav button.flag { border-color: var(--amber); color: var(--amber); }
.p66-nav button.here { border-color: var(--cyan); color: var(--cyan); }

.p66-keys { font-family: var(--fM); font-size: .74rem; color: var(--ink3); margin-top: 16px; }
.p66-keys kbd {
  background: var(--pan2); border: 1px solid var(--rule); border-radius: var(--rx);
  padding: 1px 6px; margin: 0 2px; font-size: .72rem;
}

/* -------------------------------------------------------------- results */

.p66-verdictbox { text-align: center; padding: 26px 20px; }
.p66-verdictbox .big { font-size: 3.4rem; font-weight: 800; line-height: 1; font-variant-numeric: tabular-nums; }
.p66-verdictbox .sub { font-size: 1.2rem; font-weight: 700; margin-top: 8px; }
.p66-pass { color: var(--green); }
.p66-fail { color: var(--coral); }

.p66-review { display: grid; gap: 14px; margin-top: 18px; }
.p66-rev { border: 1px solid var(--rule); border-radius: var(--rs); padding: 16px; background: var(--pan); }
.p66-rev.wrong { border-left: 3px solid var(--coral); }
.p66-rev.right { border-left: 3px solid var(--green); }
.p66-rev .stem { font-weight: 700; margin: 6px 0 10px; }
.p66-rev .ans { font-size: .9rem; margin: 3px 0; }
.p66-rev .ans.you { color: var(--coral); }
.p66-rev .ans.cor { color: var(--green); }

.p66-warn {
  background: rgba(255,176,32,.10); border-left: 3px solid var(--amber);
  border-radius: var(--rs); padding: 13px 16px; margin-bottom: 16px; font-size: .92rem;
}

@media (prefers-reduced-motion: reduce) {
  .p66 * { transition-duration: .01ms !important; }
  .p66-btn:hover, .p66-opt:hover { transform: none; }
}


/* ==========================================================================
   The launcher - the modules a learner has been given.
   Appears on the front page when signed in, so the first thing after login
   is one click from working rather than a page to navigate.
   ========================================================================== */

.p66-launch { padding: 24px 26px 28px; }
.p66-launch-head { display: flex; flex-wrap: wrap; gap: 14px; align-items: flex-start;
  margin-bottom: 20px; padding-bottom: 16px; border-bottom: 1px solid var(--rule); }
.p66-launch-head h2 { margin: 0; font-size: 1.55rem; }
.p66-launch-head .p66-access { margin-left: auto; }

.p66-launch-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 14px;
}

.p66-launch-card {
  display: flex; flex-direction: column;
  background: var(--pan); border: 1px solid var(--rule); border-radius: var(--r);
  padding: 18px 20px 16px; text-decoration: none; color: inherit;
  position: relative; overflow: hidden;
  transition: transform .14s cubic-bezier(.22,1,.36,1), border-color .14s ease;
}
a.p66-launch-card:hover { transform: translateY(-3px); border-color: var(--ruleH); }
.p66-launch-card::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 3px;
  background: linear-gradient(90deg, var(--lime), var(--cyan));
}

.p66-launch-mod {
  font-family: var(--fLabel); font-size: .66rem; font-weight: var(--labelWeight);
  letter-spacing: var(--labelTrack); text-transform: var(--labelCase); color: var(--amber);
}
.p66-launch-card h3 { margin: 5px 0 4px; font-size: 1.1rem; }
.p66-launch-spec { font-family: var(--fNum); font-size: .76rem; color: var(--ink3); margin: 0 0 14px; }

.p66-launch-meter { height: 7px; border-radius: var(--rx); background: var(--pan2); overflow: hidden; margin-bottom: 9px; }
.p66-launch-meter i { display: block; height: 100%; border-radius: var(--rx); background: var(--coral); transition: width .5s ease; }
.p66-launch-meter i.almost { background: var(--amber); }
/* 'passed' rides with 'ready' here and on the verdict below: a module on the
   learner's exam record is drawn full and green. The bar is aria-hidden and is
   never labelled a readiness score - the tile prints the result in words
   instead, because colour never carries meaning alone. */
.p66-launch-meter i.ready,
.p66-launch-meter i.passed { background: var(--green); }

.p66-launch-stat { margin: 0 0 3px; font-size: .9rem; display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.p66-launch-stat strong { font-size: 1.3rem; font-weight: 800; font-variant-numeric: tabular-nums; }
.p66-launch-verdict {
  font-family: var(--fLabel); font-size: .62rem; font-weight: var(--labelWeight); letter-spacing: var(--labelTrack);
  text-transform: var(--labelCase); padding: 3px 9px; border-radius: var(--rp); margin-left: auto;
}
.p66-launch-verdict.not_ready { background: rgba(255,92,77,.14); color: var(--coral); }
.p66-launch-verdict.almost    { background: rgba(255,176,32,.14); color: var(--amber); }
.p66-launch-verdict.ready,
.p66-launch-verdict.passed    { background: rgba(61,220,132,.14); color: var(--green); }

.p66-launch-sub { margin: 0 0 12px; font-size: .82rem; color: var(--ink3); }
.p66-launch-go {
  margin-top: auto; font-family: var(--fLabel); font-size: .8rem; font-weight: 700; color: var(--cyan);
}

@media (prefers-reduced-motion: reduce) {
  a.p66-launch-card:hover { transform: none; }
}

/* ------------------------------------------------------------------ *
 * Licence progress and the module planner - Plans/17.
 *
 * Uses the tokens declared at the top of this file, so it follows every
 * theme automatically and nothing here needs a per-theme override.
 * ------------------------------------------------------------------ */

.p66 .p66-planhead {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}

.p66 .p66-planhead h3 { margin: 2px 0 0; }

.p66 .p66-select {
  padding: 9px 12px;
  border-radius: var(--rs);
  border: 1.5px solid var(--rule);
  background: var(--pan);
  color: var(--ink);
  font: inherit;
  font-size: 15px;
  max-width: 100%;
}

.p66 .p66-select:focus-visible,
.p66 .p66-date:focus-visible,
.p66 .p66-mark:focus-visible { outline: 2px solid var(--cyan); outline-offset: 2px; }

.p66 .p66-select-sm { padding: 5px 8px; font-size: 14px; }

.p66 .p66-planmsg { margin: 10px 0 16px; }
.p66 .p66-planmsg.bad { color: var(--coral); }

.p66 .p66-plansum { margin-bottom: 16px; }

.p66 .p66-bar-lg { height: 12px; border-radius: var(--rx); margin-bottom: 14px; }

/* A quieter cousin of .p66-warn, for things worth reading but not alarming. */
.p66 .p66-note {
  background: var(--pan2);
  border-left: 4px solid var(--cyan);
  border-radius: var(--rs);
  padding: 12px 14px;
  margin: 0 0 16px;
  font-size: 15px;
}

.p66 .p66-warn.soft { border-left-color: var(--amber); }

.p66 .p66-nextplan { margin: 0 0 18px; }

.p66 .p66-reasons {
  list-style: none;
  margin: 10px 0 14px;
  padding: 0;
  font-size: 15px;
  color: var(--ink2);
}

.p66 .p66-reasons li {
  position: relative;
  padding-left: 20px;
  margin: 5px 0;
}

.p66 .p66-reasons li::before {
  content: "";
  position: absolute;
  left: 4px;
  top: 0.62em;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--lime);
}

/* The module table ------------------------------------------------- */

/* ==================================================================== *
 * THE LICENCE RECORD TABLE
 *
 * Reported 13 Sep 2026: "some text over runs or looks sloppy - make premium
 * table". Measured against the real stylesheet before touching it:
 *
 *   1024px   rows 56-66px          fits
 *    900px   rows 65-88px          fits
 *    768px   rows 66-155px         fits
 *   600px    rows 66-155px         OVERFLOWS
 *
 * ⛔ A row two and a half times the height of its neighbours. Six columns,
 * three of them form controls, against module titles up to 52 characters
 * ("Turbine Aeroplane Aerodynamics, Structures and Systems"). Nothing set a
 * column width, so the browser gave the controls their intrinsic widths and
 * left the title whatever remained - which on a laptop is not enough, so it
 * wrapped to three lines while its neighbours stayed on one.
 *
 * ⛔ AND IT HAD NO SCROLL CONTAINER AT ALL. Every other wide thing in this
 * file scrolls inside its own box; this one took the card with it.
 *
 * The fix is in two parts, and the second one matters more:
 *   - above 760px, a real table: the title column absorbs the slack, the
 *     four control columns are fixed and aligned, one row height.
 *   - below it, the table STOPS BEING A TABLE. A date picker, a number
 *     field, a select and a button in a sideways-scrolling row is not
 *     something anyone fills in on a phone. Rows become stacked blocks and
 *     each cell prints its own column name from data-th.
 * ==================================================================== */
.p66 .p66-plantbl {
  margin-top: 4px;
  /* ⛔ FIXED, OR THE COLUMN WIDTHS BELOW ARE ONLY SUGGESTIONS. Under the
     default `auto` algorithm a table is sized by its CONTENT, so a 52
     character module title sets the first column's width no matter what is
     declared for it - which is how the title column ended up too narrow for
     its own text while the table overflowed anyway. Fixed makes the declared
     widths real and lets the title ellipsis inside its box. */
  table-layout: fixed;
  width: 100%;
  /* Below this it scrolls rather than crushing the columns. The stacked
     layout takes over before that ever happens on a phone. */
  min-width: 620px;
}
.p66 .p66-plantbl tr.done td { opacity: 0.62; }

.p66 .p66-plantbl td { vertical-align: middle; }

/* One height for every row, so the eye can run down the controls. */
.p66 .p66-plantbl tbody td { height: 52px; padding-top: 6px; padding-bottom: 6px; }
.p66 .p66-plantbl tbody tr:hover td { background: var(--pan2); }

/* The title column takes the slack; the rest are fixed so they line up. */
.p66 .p66-plantbl th:nth-child(1) { width: auto; }
/* ⚠️ 118px, not 104. Three papers carry an essay and read "80 / 100m +e",
   which wrapped to a second line at the narrower width - and a wrapped cell
   sets the height of its whole row. Those three rows were 80px against 57. */
.p66 .p66-plantbl th:nth-child(2) { width: 118px; }
.p66 .p66-plantbl td[data-th="Paper"] { white-space: nowrap; }
.p66 .p66-plantbl th:nth-child(3) { width: 124px; }
.p66 .p66-plantbl th:nth-child(4) { width: 150px; }
.p66 .p66-plantbl th:nth-child(5) { width: 84px; }
.p66 .p66-plantbl th:nth-child(6) { width: 78px; }

/* ⭐ The code, the name and the chip on ONE line, each with its own job.
   The name is allowed to ellipsis rather than wrap the row to three lines -
   the full title is in the title attribute and on the tile above. */
.p66 .p66-plantbl td[data-th="Module"] {
  display: flex; align-items: baseline; gap: 8px; min-width: 0;
}
.p66 .p66-plan-code {
  font-family: var(--fNum); font-variant-numeric: tabular-nums;
  font-size: .78rem; font-weight: 700; color: var(--ink3);
  flex: none; min-width: 2.4em;
}
.p66 .p66-plan-name {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.p66 .p66-plantbl .p66-chip { flex: none; margin-left: 0; white-space: nowrap; }
.p66 .p66-plan-act { text-align: right; }

/* The controls fill their column, so four ragged widths become four edges. */
.p66 .p66-plantbl .p66-select-sm,
.p66 .p66-plantbl .p66-date,
.p66 .p66-plantbl .p66-mark { width: 100%; height: 34px; }
.p66 .p66-plantbl .p66-mark { text-align: right; }

/* ------------------------------------------------------------------ *
 * Under 760px it is not a table any more.
 * ------------------------------------------------------------------ */
@media (max-width: 760px) {
  .p66 .p66-plantbl { min-width: 0; width: 100%; }
  .p66 .p66-plantbl thead { display: none; }
  .p66 .p66-plantbl,
  .p66 .p66-plantbl tbody,
  .p66 .p66-plantbl tr,
  .p66 .p66-plantbl td { display: block; }

  .p66 .p66-plantbl tbody tr {
    border: 1px solid var(--rule); border-radius: var(--rs);
    padding: 12px 14px 14px; margin-bottom: 10px; background: var(--pan);
  }
  .p66 .p66-plantbl tbody tr:hover td { background: none; }
  .p66 .p66-plantbl tbody td {
    height: auto; padding: 0; border: 0;
    display: flex; align-items: center; gap: 10px;
  }
  /* Every cell names its own column, from data-th. */
  .p66 .p66-plantbl tbody td:not([data-th="Module"])::before {
    content: attr(data-th);
    flex: none; width: 5.2em;
    font-family: var(--fLabel); font-size: .62rem; font-weight: var(--labelWeight);
    letter-spacing: var(--labelTrack); text-transform: var(--labelCase);
    color: var(--ink3);
  }
  .p66 .p66-plantbl tbody td[data-th="Module"] {
    flex-wrap: wrap; margin-bottom: 10px;
    padding-bottom: 10px; border-bottom: 1px solid var(--rule);
  }
  /* On its own line the title has room, so let it wrap properly. */
  .p66 .p66-plantbl .p66-plan-name { white-space: normal; overflow: visible; }
  .p66 .p66-plantbl tbody td + td { margin-top: 8px; }
  .p66 .p66-plantbl td.num { text-align: left; }
  .p66 .p66-plantbl .p66-select-sm,
  .p66 .p66-plantbl .p66-date,
  .p66 .p66-plantbl .p66-mark { width: auto; flex: 1 1 auto; }
  .p66 .p66-plan-act { text-align: left; }
  .p66 .p66-plan-act .p66-btn { width: 100%; margin-top: 2px; }
}

.p66 .p66-chip {
  display: inline-block;
  margin-left: 8px;
  padding: 1px 8px;
  border-radius: var(--rp);
  border: 1px solid var(--rule);
  background: var(--pan2);
  color: var(--ink2);
  font-size: 12px;
  letter-spacing: 0.02em;
  white-space: nowrap;
}

.p66 .p66-date,
.p66 .p66-mark {
  padding: 5px 8px;
  border-radius: var(--rs);
  border: 1.5px solid var(--rule);
  background: var(--pan);
  color: var(--ink);
  font: inherit;
  font-size: 14px;
}

.p66 .p66-mark { width: 5.5em; text-align: right; }
.p66 .p66-date { width: 9.5em; }

/* Advice ------------------------------------------------------------ */

.p66 .p66-advice { margin-top: 20px; }

.p66 .p66-adv {
  border-top: 1px solid var(--rule);
  padding: 10px 0;
}

.p66 .p66-adv summary {
  cursor: pointer;
  font-weight: 600;
  list-style: none;
  position: relative;
  padding-left: 22px;
}

.p66 .p66-adv summary::-webkit-details-marker { display: none; }

.p66 .p66-adv summary::before {
  content: "+";
  position: absolute;
  left: 2px;
  color: var(--lime);
  font-family: var(--fM);
}

.p66 .p66-adv[open] summary::before { content: "\2212"; }

.p66 .p66-adv p { margin: 8px 0 4px; color: var(--ink2); }

.p66 .p66-src { margin-top: 18px; font-size: 13px; }

/* Narrow screens: the module table is the only thing here that cannot
   simply reflow, so let it scroll rather than crushing the controls.
   The hangar phone is a real use case - Plans/14. */

@media (max-width: 720px) {
  .p66 .p66-plantbl { display: block; overflow-x: auto; white-space: nowrap; }
  .p66 .p66-planhead { align-items: stretch; }
  .p66 .p66-planhead .p66-select { width: 100%; }
}

@media print {
  .p66 .p66-plantbl .p66-btn,
  .p66 .p66-plantbl select { display: none; }
  .p66 .p66-adv { display: block; }
  .p66 .p66-adv p { display: block !important; }
}

/* Launcher: licence-fit notice and mismatch mark. Plans/15 - Module 5 is
   examined as two different papers and a learner sits only one. */
.p66-launch-note {
	margin: 0 0 14px;
	padding: 10px 14px;
	border-left: 3px solid var(--amber, #d98324);
	background: color-mix(in srgb, var(--amber, #d98324) 10%, transparent);
	border-radius: var(--rx);
	font-size: .88rem;
	line-height: 1.5;
}
.p66-launch-warn {
	display: inline-block;
	margin-left: 8px;
	padding: 1px 7px;
	border-radius: var(--rp);
	background: var(--amber, #d98324);
	color: #fff;
	font-style: normal;
	font-weight: 600;
	font-size: .68rem;
	letter-spacing: .02em;
	text-transform: none;
	vertical-align: middle;
}
.p66-launch-yours {
	display: inline-block;
	margin-left: 8px;
	padding: 1px 7px;
	border-radius: var(--rp);
	background: var(--green, #2f7d4f);
	color: #fff;
	font-style: normal;
	font-weight: 600;
	font-size: .68rem;
	vertical-align: middle;
}
.p66-launch-who {
	margin: 0 0 6px;
	font-size: .84rem;
	line-height: 1.45;
	color: var(--ink, inherit);
	opacity: .9;
}

/* ------------------------------------------------------------------ *
 * The learner overview - Plans/17.
 *
 * Sits above the module library on the main screen. Every colour comes
 * from the tokens at the top of this file, so all six themes are covered
 * with no per-theme override.
 * ------------------------------------------------------------------ */

.p66 .p66-ov { display: grid; gap: 16px; margin-bottom: 26px; }

/* ⚠️ ONE COLUMN NOW. This grid held "Your next exam" beside "Exam dates";
   the next-exam card moved to the top of the screen on 13 Sep 2026 and the
   grid was left holding a single child, which a 1.35fr/1fr rule would have
   drawn at 57% width with dead space beside it. */
.p66 .p66-ov-top { display: grid; gap: 16px; grid-template-columns: 1fr; }

/* The next-exam card now leads the dashboard rather than sitting in a
   two-up, so it is allowed the full width of the screen. */
.p66 .p66-launch > .p66-ov-next { margin-bottom: 16px; }

/* --- next exam ---------------------------------------------------- */

.p66 .p66-ov-next { position: relative; overflow: hidden; }
.p66 .p66-ov-strip { position: absolute; inset: 0 auto 0 0; width: 4px; background: var(--amber); }
.p66 .p66-ov-next.empty .p66-ov-strip { background: var(--rule); }
.p66 .p66-ov-nextin { padding-left: 12px; }
.p66 .p66-ov-nextin h3 { margin: 0 0 2px; }

.p66 .p66-ov-count { display: flex; align-items: baseline; gap: 12px; margin: 12px 0 2px; }
.p66 .p66-ov-count b {
  font-family: var(--fNum); font-variant-numeric: tabular-nums;
  font-size: 3.2rem; font-weight: 600; line-height: 1; letter-spacing: -.03em;
  color: var(--amber);
}
.p66 .p66-ov-count span {
  font-family: var(--fLabel); font-size: .76rem; letter-spacing: var(--labelTrack);
  text-transform: var(--labelCase); color: var(--ink3);
}

.p66 .p66-ov-dl {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(128px, 1fr));
  gap: 14px 18px; margin: 18px 0 0; padding-top: 15px; border-top: 1px solid var(--rule);
}
.p66 .p66-ov-dl dt {
  font-family: var(--fLabel); font-size: .62rem; font-weight: var(--labelWeight);
  letter-spacing: var(--labelTrack); text-transform: var(--labelCase); color: var(--ink3); margin-bottom: 3px;
}
.p66 .p66-ov-dl dd { margin: 0; font-size: .93rem; }
.p66 .p66-ov-empty { max-width: 52ch; margin-top: 8px; }

/* --- other dates -------------------------------------------------- */

.p66 .p66-ov-dates { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.p66 .p66-ov-dates li {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  padding: 9px 12px; background: var(--pan2); border: 1px solid var(--rule);
  border-radius: var(--rs);
}
.p66 .p66-ov-dates em { font-style: normal; color: var(--ink3); margin-left: 6px; font-size: .86rem; }

/* --- status pills. A word ALWAYS accompanies the colour. ---------- */

.p66 .p66-pill {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--fLabel); font-size: .66rem; font-weight: var(--labelWeight);
  letter-spacing: var(--labelTrack); text-transform: var(--labelCase);
  padding: 4px 10px; border-radius: var(--rp); white-space: nowrap;
  border: 1px solid transparent;
}
.p66 .p66-pill::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.p66 .p66-pill.passed,
.p66 .p66-pill.ready     { color: var(--green); background: rgba(61,220,132,.12); border-color: rgba(61,220,132,.35); }
.p66 .p66-pill.failed,
.p66 .p66-pill.not_ready { color: var(--coral); background: rgba(255,92,77,.12); border-color: rgba(255,92,77,.35); }
/* 'Booked' is a scheduled state, not a warning, so it need not be warm - and
   warm is exactly the problem: measured in OKLab under a deuteranopia
   simulation, the light themes' amber and coral are deltaE 1.2 apart, which is
   indistinguishable. Violet measures 21.3 (light) and 22.7 (dark) against
   coral. Amber stays for genuine cautions like 'almost ready'. */
.p66 .p66-pill.booked    { color: var(--violet); background: rgba(180,140,255,.12); border-color: rgba(180,140,255,.35); }
.p66 .p66-pill.almost    { color: var(--amber); background: rgba(255,176,32,.12); border-color: rgba(255,176,32,.35); }
.p66 .p66-pill.training  { color: var(--cyan);  background: rgba(92,200,255,.12); border-color: rgba(92,200,255,.35); }
.p66 .p66-pill.notsat    { color: var(--ink3);  background: var(--pan2); border-color: var(--rule); }

/* --- licence prompt ----------------------------------------------- */

.p66 .p66-ov-licence { border-color: var(--ruleH); }
.p66 .p66-ov-licence .p66-small { max-width: 68ch; }

/* --- progress ------------------------------------------------------ */

.p66 .p66-ov-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
}
.p66 .p66-ov-head h3 { margin: 2px 0 0; }
.p66 .p66-ov-pct { text-align: right; margin: 0; }
.p66 .p66-ov-pct b {
  display: block; font-family: var(--fNum); font-variant-numeric: tabular-nums;
  font-size: 1.6rem; font-weight: 600; line-height: 1.1; color: var(--lime);
}
.p66 .p66-ov-pct span { font-size: .8rem; color: var(--ink3); }

.p66 .p66-ov-window {
  display: flex; gap: 16px; align-items: flex-start; flex-wrap: wrap;
  margin-top: 18px; padding: 14px 16px;
  background: var(--pan2); border: 1px solid var(--rule);
  border-left: 4px solid var(--cyan); border-radius: var(--rs);
}
.p66 .p66-ov-window b {
  font-family: var(--fNum); font-variant-numeric: tabular-nums;
  font-size: 1.35rem; font-weight: 600; color: var(--cyan); white-space: nowrap;
}
.p66 .p66-ov-window p { margin: 0; flex: 1 1 320px; color: var(--ink2); }
.p66 .p66-ov-window.watch    { border-left-color: var(--amber); }
.p66 .p66-ov-window.watch b  { color: var(--amber); }
.p66 .p66-ov-window.urgent,
.p66 .p66-ov-window.expired  { border-left-color: var(--coral); }
.p66 .p66-ov-window.urgent b,
.p66 .p66-ov-window.expired b { color: var(--coral); }

.p66 .p66-ov-next2 { margin-top: 20px; padding-top: 16px; border-top: 1px solid var(--rule); }
.p66 .p66-ov-next2 h4 { margin: 0; font-size: 1.02rem; }

/* --- the record table ---------------------------------------------- */

.p66 .p66-tablewrap { overflow-x: auto; }
.p66 .p66-ov-tbl tr.done td { opacity: .62; }
.p66 .p66-ov-tbl td { vertical-align: middle; }

/* --- forms ---------------------------------------------------------- */

.p66 .p66-ov-form {
  display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  align-items: end;
}
.p66 .p66-ov-form label {
  display: block; font-family: var(--fLabel); font-size: .6rem; font-weight: var(--labelWeight);
  letter-spacing: var(--labelTrack); text-transform: var(--labelCase); color: var(--ink3); margin-bottom: 6px;
}
.p66 .p66-ov-form input,
.p66 .p66-ov-form select {
  width: 100%; font: inherit; font-size: .9rem;
  padding: 9px 11px; border-radius: var(--rs);
  border: 1.5px solid var(--rule); background: var(--pan2); color: var(--ink);
}
.p66 .p66-ov-form input:focus-visible,
.p66 .p66-ov-form select:focus-visible { outline: 2px solid var(--cyan); outline-offset: 1px; }
.p66 .p66-ov-form .p66-btn { width: 100%; }

.p66 .p66-ov-msg { margin: 12px 0 0; min-height: 1.2em; }
.p66 .p66-ov-msg.bad { color: var(--coral); }
.p66 .p66-ov-msg.ok  { color: var(--green); }

@media print {
  .p66 .p66-ov-form, .p66 .p66-ov-msg { display: none; }
}

/* ------------------------------------------------------------------ *
 * Progress charts - Plans/17.
 *
 * Three layouts, learner's choice, default 'combined'.
 * ------------------------------------------------------------------ */

.p66 .p66-charts { margin-top: 16px; display: grid; gap: 24px; }
.p66 .p66-charts.layout-combined { grid-template-columns: 232px 1fr; align-items: start; }
@media (max-width: 780px) {
  .p66 .p66-charts.layout-combined { grid-template-columns: 1fr; }
}

/* --- the composition ring ----------------------------------------- */

.p66 .p66-donut { position: relative; width: 186px; height: 186px; margin: 0 auto; }
.p66 .p66-donut svg { width: 100%; height: 100%; }
.p66 .p66-donut-hole {
  position: absolute; inset: 0; display: grid; place-content: center; text-align: center;
}
.p66 .p66-donut-hole b {
  display: block; font-family: var(--fNum); font-variant-numeric: tabular-nums;
  font-size: 2.05rem; font-weight: 600; line-height: 1; letter-spacing: -.03em;
}
.p66 .p66-donut-hole b span { font-size: 1rem; }
.p66 .p66-donut-hole > span {
  font-family: var(--fLabel); font-size: .56rem; letter-spacing: var(--labelTrack);
  text-transform: var(--labelCase); color: var(--ink3);
}

/* --- legend. A word always, never colour alone. -------------------- */

.p66 .p66-legend { list-style: none; margin: 16px 0 0; padding: 0; display: grid; gap: 8px; }
.p66 .p66-legend li { display: flex; align-items: center; gap: 10px; font-size: .88rem; }
.p66 .p66-sw { width: 11px; height: 11px; border-radius: var(--rx); flex: none; }
.p66 .p66-legend .lb { flex: 1; }
.p66 .p66-legend .vv {
  font-family: var(--fNum); font-variant-numeric: tabular-nums; color: var(--ink2);
}
.p66 .p66-legend-row {
  display: flex; flex-wrap: wrap; gap: 8px 20px; margin-top: 12px;
}
.p66 .p66-legend-row li { flex: 0 0 auto; }
.p66 .p66-legend-row .lb { flex: 0 0 auto; }

/* --- the stacked bar ----------------------------------------------- */

.p66 .p66-stack {
  display: flex; gap: 2px; height: 32px; border-radius: var(--rx); overflow: hidden;
}
.p66 .p66-stack i { display: block; }

/* --- the module marks -------------------------------------------------- *
 *
 * One definition, in P66_Marks, rendered here and on the public grid. Each is
 * that module's own subject in line - a radical for Mathematics, a piston and
 * con-rod for Piston Engine - so a learner knows where they are before they
 * have read the title.
 *
 * ⛔ currentColor throughout, so they follow every theme with no per-theme
 * rule, and vector-effect keeps the stroke weight honest at any size.
 * ---------------------------------------------------------------------- */

.p66 .p66-mk * {
  fill: none; stroke: currentColor; stroke-width: 1.6;
  stroke-linecap: round; stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}
.p66 .p66-mk .f { fill: currentColor; stroke: none; }
.p66 .p66-mk .d { stroke-dasharray: 2.5 2.5; opacity: .55; }
/* ⭐ .a IS THE DUOTONE LAYER - the object's MASS, tinted under the stroke
   that describes it. "change them to lux premium icons of the same",
   13 Sep 2026: same subjects, because a Part-66 candidate has to recognise
   every one of them without a caption, but drawn with weight instead of as
   bare outlines. It is one declaration and it is what separates a
   considered icon set from a set of wireframes.
   ⚠️ fill-opacity, not opacity: the stroke must stay at full strength or
   the whole mark goes pale and loses its edge at 19px. */
.p66 .p66-mk .a { fill: currentColor; fill-opacity: .16; }

/* On the module card: sized to the heading it sits above. */
.p66 .p66-launch-mk {
  width: 34px; height: 34px; display: block; margin: 0 0 10px;
  color: var(--ink3);
  transition: color .14s ease;
}
.p66 a.p66-launch-card:hover .p66-launch-mk { color: var(--cyan); }
.p66 .p66-launch-card .p66-launch-mk.ready { color: var(--green); }

/* In the progress table: small, beside the code, on the text baseline. Kept
   out of the flow of the title so a long module name still wraps cleanly. */
.p66 .p66-prog-mk {
  width: 19px; height: 19px; float: left; margin: 1px 9px 0 0;
  color: var(--ink3);
}

@media (max-width: 620px) {
  .p66 .p66-prog-mk { display: none; }   /* the code alone is enough at width */
}

/* --- readiness by module -------------------------------------------- *
 *
 * This replaced a row of donut rings on 13 September 2026. The reasons are in
 * the docblock over P66_Shortcode::progress(); the short version is that
 * ranking thirteen rings means comparing thirteen angles, and the pass mark
 * was never drawn on any of them.
 *
 * ⛔ THE DATUM IS THE POINT. .p66-prog-datum is the 75 mark. It is drawn on
 * every row, it sits ABOVE the fill so a full bar cannot hide it, and it is
 * the reason this is a table rather than a list of numbers.
 * ------------------------------------------------------------------- */

.p66 .p66-prog { overflow-x: auto; }
.p66 .p66-progtbl { width: 100%; border-collapse: collapse; font-size: .92rem; }

.p66 .p66-progtbl thead th {
  font-family: var(--fLabel); font-size: .6rem; font-weight: var(--labelWeight); letter-spacing: var(--labelTrack);
  text-transform: var(--labelCase); color: var(--ink3); text-align: left;
  padding: 0 14px 7px 0; border-bottom: 1px solid var(--ruleH); white-space: nowrap;
}
.p66 .p66-progtbl tbody td,
.p66 .p66-progtbl tbody th {
  padding: 10px 14px 10px 0; border-bottom: 1px solid var(--rule);
  vertical-align: middle; text-align: left; font-weight: 400;
}
.p66 .p66-progtbl tbody tr:last-child td { border-bottom: 0; }

.p66 .p66-prog-mod { min-width: 148px; }
.p66 .p66-prog-mod a { font-weight: 700; text-decoration: none; color: var(--ink); }
.p66 .p66-prog-mod a:hover { text-decoration: underline; }
.p66 .p66-prog-mod em {
  display: block; font-style: normal; font-size: .82rem; color: var(--ink2);
  line-height: 1.3; margin-top: 1px;
}

.p66 .p66-prog-bar-h { width: 45%; }
.p66 .p66-prog-bar { width: 45%; min-width: 130px; }
.p66 .p66-prog-track {
  position: relative; display: block; height: 12px;
  background: var(--pan2); border-radius: var(--rx); overflow: visible;
}
.p66 .p66-prog-track i {
  display: block; height: 100%; border-radius: var(--rx);
  background: var(--coral); transition: width .5s ease;
}
/* The verdict classes P66_Licence::pill() already returns - same words, same
   colours as the module cards, so one module reads the same in both places. */
.p66 .p66-prog-track i.almost    { background: var(--amber); }
.p66 .p66-prog-track i.ready,
.p66 .p66-prog-track i.ready_mcq { background: var(--green); }
.p66 .p66-prog-track i.passed    { background: var(--green); }

.p66 .p66-prog-datum {
  position: absolute; top: -4px; bottom: -4px; width: 2px;
  background: var(--ink); opacity: .55; pointer-events: none;
}

.p66 .p66-prog-num {
  text-align: right; font-family: var(--fNum); font-weight: 600;
  font-variant-numeric: tabular-nums; width: 56px;
}
.p66 .p66-prog-verdict {
  font-family: var(--fLabel); font-size: .62rem; font-weight: var(--labelWeight); letter-spacing: var(--labelTrack);
  text-transform: var(--labelCase); padding: 3px 9px; border-radius: var(--rp);
  white-space: nowrap; display: inline-block;
}
.p66 .p66-prog-verdict.not_ready { background: rgba(255,92,77,.14); color: var(--coral); }
.p66 .p66-prog-verdict.almost    { background: rgba(255,176,32,.14); color: var(--amber); }
.p66 .p66-prog-verdict.ready,
.p66 .p66-prog-verdict.ready_mcq,
.p66 .p66-prog-verdict.passed    { background: rgba(61,220,132,.14); color: var(--green); }
.p66 .p66-prog-short {
  font-style: normal; font-family: var(--fNum); font-size: .68rem;
  color: var(--ink3); margin-left: 8px; white-space: nowrap;
}

/* ⛔ The untouched modules, named. Quiet, but never absent - a learner who
   is avoiding Module 10 must still be reminded Module 10 exists. */
/* ⭐ THE SUB-CATEGORY, WHEREVER A SPLIT MODULE IS NAMED.
 *
 * Module 5 is the one module examined as two different papers, and a learner
 * sits ONE. Both are shown on purpose - hiding something a learner has been
 * granted is worse than showing it with a caution - but "two module 5" was
 * reported on 13 Sep 2026 because the two were IDENTICAL everywhere the eye
 * actually lands. A caution nobody can act on is a coin toss.
 *
 * Quiet on purpose: it identifies the paper, it is not a feature of it. */
.p66 .p66-launch-cat,
.p66 .p66-prog-cat,
.p66 .p66-rest-cat {
  font-family: var(--fNum); font-variant-numeric: tabular-nums;
  font-weight: 700; color: var(--cyan); white-space: nowrap;
}
.p66 .p66-launch-cat { margin-left: 7px; font-size: .92em; }
.p66 .p66-prog-cat   { margin-left: 6px; font-weight: 600; font-style: normal; }
.p66 .p66-rest-cat   { margin-left: 1px; font-weight: 700; opacity: .85; }

/* ⭐ THE FOUR GATES ON A MODULE CARD.
 *
 * "more stats or details in the module cards, like if the drills have been
 * completed... keep it tight in the cards space but more info and colours"
 * - 13 Sep 2026.
 *
 * Four equal columns, tabular figures, one line of label under each. It
 * replaces a single sentence ("74% covered · 2 papers sat") and costs about
 * the same height, because the figures are what carry it rather than prose.
 *
 * ⛔ COLOUR IS A SECOND ENCODING, NEVER THE ONLY ONE. Every cell prints its
 * figure and its name and carries the target in its title; the tint repeats
 * what is already written. That rule is not negotiable here - see the note
 * over composition_states() in class-shortcode.php.
 *
 * ⚠️ .none is an UNMEASURED gate, not a failed one. It draws em-dash grey,
 * deliberately not coral: a learner who has not sat a mock yet has not
 * failed anything. */
.p66 .p66-gates {
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: 1px; margin: 12px 0 10px; padding: 0;
  background: var(--rule); border: 1px solid var(--rule);
  border-radius: var(--rx); overflow: hidden;
}
.p66 .p66-gates > div {
  background: var(--pan); padding: 7px 4px 6px; text-align: center;
}
.p66 .p66-gates dt {
  font-family: var(--fLabel); font-size: .56rem; font-weight: var(--labelWeight);
  letter-spacing: var(--labelTrack); text-transform: var(--labelCase);
  color: var(--ink3); margin: 2px 0 0; order: 2;
}
.p66 .p66-gates dd {
  margin: 0; font-family: var(--fNum); font-variant-numeric: tabular-nums;
  font-size: .92rem; font-weight: 700; line-height: 1.15; color: var(--ink2);
}
.p66 .p66-gates > div { display: flex; flex-direction: column; }
.p66 .p66-gates .met  dd { color: var(--green); }
.p66 .p66-gates .near dd { color: var(--amber); }
.p66 .p66-gates .short dd { color: var(--coral); }
.p66 .p66-gates .none dd { color: var(--ink3); }
.p66 .p66-gates .met  { background: var(--greenBg); }

@media (max-width: 380px) {
  /* Two by two rather than four squeezed columns. */
  .p66 .p66-gates { grid-template-columns: repeat(2, 1fr); }
}

/* ⭐ THE UNTOUCHED MODULES - a scannable row, not a paragraph.
 *
 * Was a table cell holding up to seventeen full module titles run together
 * with middots, inside the table as a row that was not a row. Reported as
 * "just a bunch of text nothing to separate or look good". It is now codes
 * only, outside the table, in a wrapping row of chips - the full titles are
 * on the tiles above, where they are drawn once with their marks. */
.p66 .p66-rest {
  margin-top: 14px; padding-top: 13px; border-top: 1px solid var(--rule);
}
.p66 .p66-rest-lead {
  margin: 0 0 9px; font-size: .82rem; color: var(--ink2);
}
.p66 .p66-rest-lead strong {
  font-family: var(--fNum); font-variant-numeric: tabular-nums;
  color: var(--ink); font-weight: 700;
}
.p66 .p66-rest-lead em { font-style: normal; color: var(--ink3); }
.p66 .p66-rest-chips {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: 6px;
}
.p66 .p66-rest-chips a,
.p66 .p66-rest-chips span {
  display: inline-block; padding: 4px 10px;
  border: 1px solid var(--rule); border-radius: var(--rp);
  background: var(--pan2); color: var(--ink2);
  font-family: var(--fNum); font-size: .74rem; font-weight: 600;
  font-variant-numeric: tabular-nums; text-decoration: none;
  transition: border-color .14s ease, color .14s ease, background .14s ease;
}
.p66 .p66-rest-chips a:hover {
  border-color: var(--cyan); color: var(--cyan); background: var(--pan);
}
.p66 .p66-rest-chips a:focus-visible {
  outline: 2px solid var(--cyan); outline-offset: 2px;
}

.p66 .p66-ringcard { margin-bottom: 16px; }

/* Visible to a screen reader, not on screen. The table's caption states the
   pass mark, which sighted readers get from the datum line. */
.p66 .p66-sr {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

@media (max-width: 620px) {
  .p66 .p66-progtbl { font-size: .86rem; }
  .p66 .p66-prog-mod { min-width: 110px; }
  .p66 .p66-prog-bar, .p66 .p66-prog-bar-h { width: 32%; min-width: 84px; }
  .p66 .p66-prog-short { display: none; }
}

/* --- the layout picker ---------------------------------------------- */

.p66 .p66-headright {
  margin-left: auto; display: flex; gap: 16px; align-items: flex-end; flex-wrap: wrap;
}
.p66 .p66-headright .p66-access { margin-left: 0; }

.p66 .p66-layoutpick { margin-left: auto; text-align: right; }
.p66 .p66-headright .p66-layoutpick { margin-left: 0; }
.p66 .p66-layoutpick label {
  display: block; font-family: var(--fLabel); font-size: .58rem; font-weight: var(--labelWeight);
  letter-spacing: var(--labelTrack); text-transform: var(--labelCase); color: var(--ink3); margin-bottom: 5px;
}
.p66 .p66-layoutpick select {
  font: inherit; font-size: .82rem; padding: 6px 9px; border-radius: var(--rs);
  border: 1.5px solid var(--rule); background: var(--pan2); color: var(--ink);
}
.p66 .p66-layoutpick select:focus-visible { outline: 2px solid var(--cyan); outline-offset: 1px; }

@media print {
  .p66 .p66-layoutpick { display: none; }
}

/* ------------------------------------------------------------------ *
 * Anchors that are dressed as components.
 *
 * A link styled as a button keeps WordPress's global link colour: its
 * `:root :where(a:not(.wp-element-button))` rule lands at (0,1,0), the same
 * specificity as a bare class, and prints after ours - so it wins. On the
 * primary button that put dark link text on a dark gradient and the label
 * disappeared.
 *
 * Naming the element takes the selector to (0,2,1) and settles it. The theme
 * already carries this fix for its own `a.btn.btn-primary`; the plugin's
 * buttons never got it. Applies to every anchor we style as something other
 * than a link, so the next one added is covered too.
 * ------------------------------------------------------------------ */

.p66 a.p66-btn,
.p66 a.p66-btn:hover,
.p66 a.p66-btn:focus,
.p66 a.p66-btn:visited { text-decoration: none; }

.p66 a.p66-btn-primary,
.p66 a.p66-btn-primary:hover,
.p66 a.p66-btn-primary:focus,
.p66 a.p66-btn-primary:visited { color: var(--accInk); }

.p66 a.p66-btn-ghost,
.p66 a.p66-btn-ghost:hover,
.p66 a.p66-btn-ghost:focus,
.p66 a.p66-btn-ghost:visited { color: var(--ink); }

.p66 a.p66-launch-card,
.p66 a.p66-launch-card:hover,
.p66 a.p66-launch-card:visited { color: inherit; text-decoration: none; }

/* ------------------------------------------------------------------ *
 * Essay practice - Plans/28.
 * ------------------------------------------------------------------ */

.p66 .p66-essay-intro { margin-bottom: 16px; }
.p66 .p66-essay-intro p + p { margin-top: 9px; }

.p66 .p66-essay-grid {
  display: grid; gap: 14px;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
}
.p66 .p66-essay-card { display: flex; flex-direction: column; gap: 9px; }
.p66 .p66-essay-card h3 { margin: 0; font-size: 1rem; line-height: 1.4; }
.p66 .p66-essay-go { margin-top: auto; padding-top: 6px; display: flex; gap: 8px; flex-wrap: wrap; }

.p66 .p66-essay-topic {
  font-family: var(--fLabel); font-size: .64rem; font-weight: var(--labelWeight);
  letter-spacing: var(--labelTrack); text-transform: var(--labelCase);
  color: var(--cyan); background: rgba(92,200,255,.12);
  border: 1px solid rgba(92,200,255,.3);
  padding: 3px 9px; border-radius: var(--rp); align-self: flex-start;
}

.p66 .p66-essay-top { display: flex; justify-content: space-between; align-items: center; gap: 12px; margin-bottom: 12px; }
.p66 .p66-essay-stem { margin: 0 0 4px; font-size: 1.1rem; line-height: 1.45; }

.p66 .p66-essay-plan {
  margin: 12px 0; padding: 10px 13px; border-radius: var(--rs);
  background: color-mix(in srgb, var(--lime) 12%, transparent);
  border-left: 3px solid var(--lime);
  font-size: .88rem;
}

.p66 .p66-essay-area {
  width: 100%; margin-top: 12px; padding: 14px 16px;
  border-radius: var(--rs); border: 1.5px solid var(--rule);
  background: var(--pan2); color: var(--ink);
  font: inherit; font-size: .96rem; line-height: 1.7; resize: vertical;
}
.p66 .p66-essay-area:focus-visible { outline: 2px solid var(--cyan); outline-offset: 1px; }

.p66 .p66-essay-paper {
  margin-top: 12px; padding: 22px; border-radius: var(--rs);
  border: 2px dashed var(--rule); background: var(--pan2); text-align: center;
}
.p66 .p66-essay-paper p:first-child { font-size: 1.05rem; font-weight: 600; }
.p66 .p66-essay-paper p + p { margin-top: 7px; }

.p66 .p66-essay-words { margin-top: 14px; }
.p66 .p66-essay-words label {
  display: block; font-family: var(--fLabel); font-size: .6rem; font-weight: var(--labelWeight);
  letter-spacing: var(--labelTrack); text-transform: var(--labelCase); color: var(--ink3); margin-bottom: 6px;
}
.p66 .p66-essay-words input {
  width: 140px; font: inherit; font-size: .92rem; padding: 8px 11px;
  border-radius: var(--rs); border: 1.5px solid var(--rule);
  background: var(--pan2); color: var(--ink);
}
.p66 .p66-essay-words p { margin-top: 7px; max-width: 60ch; }

.p66 .p66-essay-yours {
  margin-top: 12px; padding: 15px 17px; border-radius: var(--rs);
  background: var(--pan2); border: 1px solid var(--rule);
  white-space: pre-wrap; font-size: .94rem; line-height: 1.7;
}

/* --- the marking grid --- */

.p66 .p66-essay-mark {
  display: grid; gap: 16px; grid-template-columns: 1fr 320px; align-items: start;
  margin-top: 16px;
}
@media (max-width: 900px) { .p66 .p66-essay-mark { grid-template-columns: 1fr; } }

.p66 .p66-kp {
  border-top: 1px solid var(--rule); padding: 14px 0;
  display: grid; grid-template-columns: 1fr auto; gap: 10px 16px; align-items: start;
}
.p66 .p66-kp:first-of-type { border-top: 0; }
.p66 .p66-kp-txt { min-width: 0; }
.p66 .p66-kp-txt b { display: block; margin-bottom: 3px; }
.p66 .p66-kp-opt {
  display: block; margin-top: 4px; font-style: normal;
  font-family: var(--fLabel); font-size: .6rem; letter-spacing: var(--labelTrack);
  text-transform: var(--labelCase); color: var(--ink3);
}
.p66 .p66-kp-ev {
  width: 100%; margin-top: 8px; font: inherit; font-size: .85rem;
  padding: 7px 10px; border-radius: var(--rs);
  border: 1.5px solid var(--rule); background: var(--pan2); color: var(--ink);
}
.p66 .p66-kp-ev:focus-visible { outline: 2px solid var(--cyan); outline-offset: 1px; }
.p66 .p66-kp-err {
  margin-top: 8px; font: inherit; font-family: var(--fLabel);
  font-size: .62rem; font-weight: var(--labelWeight); letter-spacing: var(--labelTrack); text-transform: var(--labelCase);
  padding: 4px 10px; border-radius: var(--rp); cursor: pointer;
  border: 1px solid var(--rule); background: var(--pan2); color: var(--ink3);
}
.p66 .p66-kp-err[aria-pressed="true"] {
  color: var(--coral); background: rgba(255,92,77,.12); border-color: rgba(255,92,77,.45);
}
.p66 .p66-kp-err:focus-visible { outline: 2px solid var(--cyan); outline-offset: 2px; }

.p66 .p66-lights { display: flex; gap: 6px; }
.p66 .p66-light {
  width: 38px; height: 34px; border-radius: var(--rx); cursor: pointer;
  border: 1.5px solid var(--rule); background: var(--pan2);
  display: grid; place-items: center;
  font-family: var(--fNum); font-size: .7rem; font-weight: 600; color: var(--ink3);
}
.p66 .p66-light:hover { border-color: var(--ruleH); }
.p66 .p66-light:focus-visible { outline: 2px solid var(--cyan); outline-offset: 2px; }
.p66 .p66-light[aria-pressed="true"].g { background: rgba(61,220,132,.16); border-color: var(--green); color: var(--green); }
.p66 .p66-light[aria-pressed="true"].a { background: rgba(255,176,32,.16); border-color: var(--amber); color: var(--amber); }
.p66 .p66-light[aria-pressed="true"].r { background: rgba(255,92,77,.16); border-color: var(--coral); color: var(--coral); }

/* --- verdict --- */

.p66 .p66-essay-verdict { position: sticky; top: 14px; }
@media (max-width: 900px) { .p66 .p66-essay-verdict { position: static; } }
.p66 .p66-essay-big {
  font-family: var(--fNum); font-weight: 600; font-size: 1.5rem;
  letter-spacing: -.02em; line-height: 1; padding: 10px 0 2px;
}
.p66 .p66-essay-big.pass { color: var(--green); }
.p66 .p66-essay-big.fail { color: var(--coral); }

.p66 .p66-conds { display: grid; gap: 9px; margin-top: 16px; }
.p66 .p66-conds div {
  display: flex; gap: 10px; align-items: flex-start; font-size: .87rem;
  padding: 10px 12px; border-radius: var(--rs);
  background: var(--pan2); border: 1px solid var(--rule);
}
.p66 .p66-conds .ic { font-family: var(--fLabel); font-weight: 600; flex: none; }
.p66 .p66-conds div.good .ic { color: var(--green); }
.p66 .p66-conds div.bad { border-color: rgba(255,92,77,.4); background: rgba(255,92,77,.10); }
.p66 .p66-conds div.bad .ic { color: var(--coral); }
.p66 .p66-conds div.warnrow .ic { color: var(--amber); }

.p66 .p66-essay-hist { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.p66 .p66-essay-hist li {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 9px 12px; border-radius: var(--rs);
  background: var(--pan2); border: 1px solid var(--rule); font-size: .89rem;
}
.p66 .p66-essay-hist li b { margin-left: auto; color: var(--ink2); font-size: .82rem; }

@media print {
  .p66 .p66-lights, .p66 .p66-kp-err, .p66 .p66-essay-go { display: none; }
}

/* ------------------------------------------------------------------ */
/* Confidence — "were you sure?", asked between the answer and the     */
/* verdict. APPENDED, per the handover rule for shared files: nothing  */
/* above this line is touched, and no colour is redeclared — every     */
/* value here is a token already defined on .p66.                      */
/* ------------------------------------------------------------------ */

.p66 .p66-conf {
  margin-top: 16px; padding: 13px 15px;
  border: 1px dashed var(--rule); border-radius: var(--rs);
  background: var(--pan2);
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
}
.p66 .p66-conf .q {
  font-family: var(--fLabel); font-size: .78rem; letter-spacing: .04em;
  color: var(--ink2); flex: 1 1 220px;
}
.p66 .p66-conf .b { display: flex; gap: 8px; }
.p66 .p66-conf .b button { display: inline-flex; align-items: center; gap: 8px; }
.p66 .p66-conf .b .k {
  font-family: var(--fM); font-size: .66rem; font-weight: 700;
  padding: 1px 5px; border-radius: var(--rx);
  background: var(--pan); color: var(--ink3);
}
.p66 .p66-conf .x { display: flex; gap: 12px; }

.p66 .p66-link {
  background: none; border: 0; padding: 0; cursor: pointer;
  font: inherit; font-size: .78rem; color: var(--ink3);
  text-decoration: underline; text-underline-offset: 3px;
}
.p66 .p66-link:hover { color: var(--ink2); }

/* The two confidence states that mean something. Colour comes from the
   existing .p66-fb border-left convention, so it reads as one more note
   in the same stack rather than a new kind of thing. */
.p66 .p66-fb .p66-conf-note { border-color: var(--lime); }
.p66 .p66-fb .p66-conf-note.bad { border-color: var(--coral); }

@media print {
  .p66 .p66-conf { display: none; }
}

/* Session length picker. A row of buttons rather than a <select>, because
   this is a four-way choice made with a thumb in a hangar, and a native
   select on a phone is a full-screen modal for something that should be one
   tap. Wraps rather than scrolls on a narrow screen. */
.p66 .p66-seg { display: flex; flex-wrap: wrap; gap: 8px; margin: 10px 0 12px; }
.p66 .p66-seg .p66-btn { min-width: 62px; justify-content: center; }

/* A plain wrapping row of buttons. Added with the notes card (Plans/62);
   every other button row on this screen had grown its own class. */
.p66-row { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
