/* ============================================================================================
   SOPHRON PORTAL SHELL (20 Oct 2026). One layout for every program portal: the Analyst Program
   (and its tracks, Equity and Quant), the Options Course with Sven Hubens, and every track after.
   Vincent: "each page can have different content, the menu on left also, but the layout must
   always look the same, so the menu in same place, buttons in same place, modules must all have
   the same layout."

   The reference is the Analyst Program portal as it renders on sophron.eu (its inline layout in
   analyst/portal.html + the Sophron skin in sph-portal.css). This file holds those values ONCE.
   A program supplies content and menu items only; it does not restyle anything below.
   Load it LAST on every portal page, after the program's own CSS. Rules are written
   `html body ...` so they win over the older copies still sitting in the program files.

   The pieces, in page order:
     1. Page grid ............ .ao-shell (sidebar column + main column)
     2. Sidebar .............. .ao-side > .ao-side__card > .ao-me (profile) + nav.ao-tabs
                               (.ao-tab, .ao-navgroup, .ao-tab__badge)
     3. Page title ........... .aj__top / h1.ao-h
     4. Module reader ........ .aj-fb (sticky top bar: Back / Full screen / Next module),
                               .aj__grid (lesson + right panel .aj__side), #ocm-lesson
     5. Previous / Next ...... .ocm-nav at the end of a lesson: PINNED to the bottom of the
                               screen, side by side on the left, the same width
                               (Vincent, 20 Oct 2026, for every program)
     6. Tests ................ .ocm-test, .ocp-quiz__opt, .ocp-btn: square 2px corners
   Sticky offsets read --aj-stick-top (the site header's height), set by sph-shell.js.
   Colours come from the Sophron tokens; a program with a dark mode overrides the --sh-* tokens.
   ============================================================================================ */
:root {
  --sh-side: 248px;          /* sidebar column */
  --sh-right: 316px;         /* right-hand panel next to a lesson */
  --sh-gap: 26px;            /* lesson to right panel */
  --sh-fb-h: 40px;           /* the module top bar (.aj-fb) the right panel pins under */
  --sh-r: 2px;               /* corners of buttons, options, pager, test box */
  --sh-bg: var(--sph-cream, #f6f3ee);
  --sh-card: var(--sph-paper, #fbf9f5);
  --sh-line: var(--sph-line, rgba(3,2,72,.14));
  --sh-ink: var(--sph-ink, #030248);
  --sh-ink-soft: var(--sph-ink-soft, rgba(3,2,72,.7));
  --sh-hover: var(--sph-cream, #f6f3ee);
  --sh-accent: var(--sph-burg, #66100c);
  --sh-on-accent: var(--sph-cream, #f6f3ee);
  --sh-muted: var(--sph-body-soft, rgba(26,20,16,.62));
}

/* 1. Page grid ------------------------------------------------------------------------------ */
/* The site header stays pinned on every portal, so the sidebar and the module top bar sit under it. */
html body .sph-topnav { position: sticky; top: 0; z-index: 900; }
html body .ao-shell { display: grid; grid-template-columns: var(--sh-side) minmax(0, 1fr); gap: 0; align-items: start; min-height: 70vh; margin: 1.25rem 0; padding: 0 24px; max-width: none; }
html body .ao-main { min-width: 0; padding-left: 6px; }

/* 2. Sidebar -------------------------------------------------------------------------------- */
/* NO SITE FOOTER IN A PORTAL (9 Nov 2026, Vincent chose "drop footer in portal"): on a short tab the 177px site footer
   pushed the pinned menu up at the bottom of the page and it snapped back on the next tab switch. While a portal (a
   shown .ao-shell with its menu) is on the page the footer is not drawn, so the menu never moves; the signed-out
   landing page in the same file, where every .ao-shell is display:none, keeps its footer. */
html body:has(.ao-shell:not([style*="none"]):not([hidden]) > .ao-side) .sph-foot { display: none; }
/* PINNED WHERE IT RESTS (9 Nov 2026, Vincent: "why does left menu go up on each tab switch? it's not fixed to top
   aligned"): the menu rests 1.25rem (the shell's margin) under the site header, so it pins at exactly that height. A
   fixed 88px pinned it 10px above its resting place under the 78px header: it jumped up on the first scroll and back
   down on every tab switch (which scrolls to the top). --aj-stick-top = the header's height, set by sph-shell.js. */
html body .ao-side { position: sticky; top: calc(var(--aj-stick-top, 68px) + 1.25rem); align-self: start; padding-right: 18px; z-index: 45; }
/* THE WHOLE MENU, ALWAYS (Vincent, 5 Nov 2026: "always show full side menu on left", "and even full menu when folding
   out courses"): no inner scroll box. The menu stays pinned while it fits on the screen; when it is taller (Courses
   and Tools folded out) it scrolls with the page instead (sph-shell.js adds .sh-side-tall), so no item is ever cut off. */
@media (min-width: 901px) {
  html body .ao-side { padding: 2px 18px 22px 6px; margin-left: -6px; }
  html body .ao-side.sh-side-tall { position: relative; top: 0; }
}
html body .ao-side__card { background: var(--sh-card); border: 1px solid var(--sh-line); border-radius: 12px; padding: 14px; box-shadow: none; }
html body .ao-me { display: flex; align-items: center; gap: 10px; margin: 0 0 10px; padding: 6px 6px 12px; background: none; border: 0; border-bottom: 1px solid var(--sh-line); border-radius: 0; }
html body .ao-me__pic { flex: none; width: 42px; height: 42px; border-radius: 50%; object-fit: cover; box-sizing: border-box; background: var(--sph-cream-deep, #ede8df); border: 2px solid var(--sph-cream-deep, #ede8df); }
html body .ao-me__name { display: inline-block; font-family: var(--sph-serif); font-size: 1.05rem; font-weight: 700; line-height: 1.1; color: var(--sh-ink); text-decoration: none; }
html body a.ao-me__name:hover { color: var(--sh-accent); text-decoration: underline; }
html body .ao-me__role { margin-top: 2px; font-family: var(--sph-sans); font-size: .74rem; color: var(--sh-muted, var(--sph-body-soft, rgba(26,20,16,.62))); }
html body .ao-me__logout { display: inline-block; margin-top: 4px; padding: 0; border: 0; background: none; cursor: pointer; font: inherit; font-family: var(--sph-sans); font-size: .64rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--sh-accent); }
html body .ao-me__logout:hover { text-decoration: underline; }
/* The edit button on the right of the profile box, the same in all five portals (7 Nov 2026, "make all consistent"; it was
   on the Analyst and Quant Program only). Sign out is on the account page (Vincent, 21 Oct 2026), not in the box. */
html body .ao-me__edit { margin-left: auto; align-self: center; flex-shrink: 0; width: 30px; height: 30px; box-sizing: border-box; border-radius: 9px; display: inline-flex; align-items: center; justify-content: center; color: var(--sh-muted, rgba(26,20,16,.62)); border: 1px solid var(--sh-line, rgba(3,2,72,.14)); background: #fff; transition: color .15s, border-color .15s, background .15s; }
html body .ao-me__edit:hover { color: var(--sh-accent, #66100c); border-color: rgba(102,16,12,.22); background: rgba(102,16,12,.06); }
html body .ao-me__edit svg { width: 15px; height: 15px; }
html body .ao-tabs { display: flex; flex-direction: column; gap: 2px; }
html body .ao-tabs .ao-tab { display: flex; align-items: center; gap: 10px; width: 100%; box-sizing: border-box; min-height: 0; margin: 0; padding: 9px 12px; border: 0; border-radius: 8px; background: none; box-shadow: none;
  color: var(--sh-ink-soft); font: inherit; font-family: var(--sph-sans); font-size: .9rem; font-weight: 600; line-height: 1.2; letter-spacing: 0; text-transform: none; text-align: left; text-decoration: none; white-space: nowrap; cursor: pointer; transition: background .15s, color .15s; }
html body .ao-tabs .ao-tab:hover { background: var(--sh-hover); color: var(--sh-ink); }
html body .ao-tabs .ao-tab.active { background: var(--sh-accent); color: var(--sh-on-accent); box-shadow: none; }
html body .ao-tab__badge { margin-left: auto; font-size: .68rem; font-weight: 800; padding: 1px 7px; border-radius: var(--sh-r); background: var(--sph-burg-soft, rgba(102,16,12,.06)); color: var(--sh-accent); }
html body .ao-tab.active .ao-tab__badge { background: rgba(255,255,255,.25); color: #fff; }
html body .ao-navgroup { margin-top: 8px; padding: 16px 12px 4px; border-top: 1px solid var(--sh-line); font-family: var(--sph-sans); font-size: .75rem; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: #9ca3af; }
@media (max-width: 900px) {
  html body .ao-shell { grid-template-columns: 1fr; min-height: 0; }
  html body .ao-side { position: relative; top: 0; padding-right: 0; max-height: none; overflow: visible; margin-left: 0; }
  html body .ao-tabs { flex-direction: row; flex-wrap: wrap; gap: 6px; }
  html body .ao-tabs .ao-tab { width: auto; flex: 0 1 auto; padding: 9px 13px; }
  html body .ao-navgroup { flex-basis: 100%; border-top: 0; padding-top: 8px; }
}

/* 3. Page title ----------------------------------------------------------------------------- */
html body .aj__top { display: flex; justify-content: space-between; align-items: baseline; gap: 16px; flex-wrap: wrap; margin: 0 0 24px; padding: 0 0 20px; border-bottom: 1px solid var(--sh-line); }
html body .ao-main h1.ao-h, html body .aj__top h1 { font-family: var(--sph-serif); font-weight: 400; font-size: 1.85rem; line-height: 1.2; letter-spacing: -.01em; color: var(--sh-ink); margin: 0; }

/* 4. Module reader -------------------------------------------------------------------------- */
/* Top bar while a module is open: Back to the journey, Full screen, Next module. Pinned under the site header. */
html body .aj-fb { position: sticky; top: calc(var(--aj-stick-top, 88px) + var(--aj-map-h, 0px)); z-index: 24; display: flex; justify-content: space-between; align-items: center; gap: 12px;
  margin: 0; padding: 8px 0; background: var(--sh-bg); border-bottom: 1px solid var(--sh-line); border-radius: 0; font-size: 13px; line-height: 1.3; }
html body .aj-fb[hidden] { display: none; }
html body .aj-fb__b { appearance: none; background: none; border: 0; padding: 3px 0; margin: 0; font: inherit; font-family: var(--sph-sans); font-size: 13px; font-weight: 400; color: var(--sh-ink-soft); text-decoration: none; cursor: pointer;
  display: inline-flex; align-items: center; gap: 6px; min-width: 0; max-width: 100%; white-space: nowrap; }
html body .aj-fb__b:hover { color: var(--sh-accent); text-decoration: none; }
html body .aj-fb__b span { overflow: hidden; text-overflow: ellipsis; font-weight: inherit; color: inherit; }
html body .aj-fb__next { margin-left: auto; text-align: right; }
html body .aj-fb__full svg { width: 12px; height: 12px; flex: none; }
html body.ap-full .aj-fb__full { color: var(--sh-accent); }
/* Lesson + right panel. The lesson always fills the space up to the panel. The analyst Journey uses
   .aj__grid with .aj__side; a program's own reader adds .sh-reader to the same grid. */
/* Only the program's own reader grid (.sh-reader). The analyst Journey's .aj__grid keeps its own rules, including
   .aj__grid--single (no right panel = the list takes the full width); the shell must never override those. */
html body .aj__grid.sh-reader { display: grid; grid-template-columns: minmax(0, 1fr) var(--sh-right); gap: var(--sh-gap); align-items: start; }
/* clear of the module top bar (Back / Full screen / Next module) with a little air: Vincent, 20 Oct 2026 */
html body .sh-reader > .aj__side { position: sticky; top: calc(var(--aj-stick-top, 88px) + 72px); grid-column: auto; display: block;
  max-height: calc(100vh - var(--aj-stick-top, 88px) - 84px); overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin; }
/* AIR ABOVE THE PANEL (Vincent, 7 Nov 2026: "add top margin above this block everywhere"). The Options Course's own
   .aj__side rule (aj-journey.css, !important) pinned the panel 10 px under the site header, so "Your reading position"
   slid under the module top bar. It now pins under that bar (--sh-fb-h) with the 18 px the panel's blocks keep between
   them, also before it pins. The same values as the analyst and module reader's panel (ap-lessons.js, .apl-side). */
html body .sh-reader > .aj__side { top: calc(var(--aj-stick-top, 88px) + var(--aj-map-h, 0px) + var(--sh-fb-h, 40px)) !important; box-sizing: border-box; padding: 18px 0;
  max-height: calc(100vh - var(--aj-stick-top, 88px) - var(--aj-map-h, 0px) - var(--sh-fb-h, 40px)); }
html body .sh-reader > .aj__side .ocm-card { border-radius: 12px; }   /* cards keep 12 px corners (rule book 2) */
/* Labels at the rule book's 0.75 rem (Options set them at 0.7), the number with 8 px under it: as ap-lessons.js .apl-side. */
html body .sh-reader > .aj__side .k { font-size: .75rem; }
html body .sh-reader > .aj__side .ocm-pos__big { margin-bottom: 8px; }
html body .sh-reader > .ocm-left { display: none; }
html body .sh-reader > .ocm-lesson { min-width: 0; width: 100%; box-sizing: border-box; }   /* never wider than its column (a wide table ran under the panel) */
html body .sh-reader .ocm-lesson, html body .aj--focus .apl .ocm-lesson, html body .aj--focus .apl .ocm-nav { max-width: none; }
/* No right panel, no right column (Vincent, 20 Oct 2026: "if there is no right side panel, at least fill the whole
   screen with the module outline"): an empty or hidden side panel gives its width back to the module. */
html body .aj__grid:has(> .aj__side:empty), html body .aj__grid:has(> .aj__side[hidden]) { grid-template-columns: minmax(0, 1fr); }
/* Full screen (the toggle in the top bar, kept per browser as ap.readerFull) hides the sidebar and the
   right panel while a module is open. Under 1180px the right panel would stack above the lesson, so it hides. */
/* Full screen no longer hides the menu (5 Nov 2026, "always show full side menu"): only the right panel goes. */
html body.ap-full .sh-reader, html body.ap-full .aj--focus .aj__grid { grid-template-columns: minmax(0, 1fr); }
html body.ap-full .sh-reader > .aj__side, html body.ap-full .aj--focus .aj__side { display: none; }
@media (max-width: 1180px) {
  html body .sh-reader, html body .aj--focus .aj__grid { grid-template-columns: minmax(0, 1fr); }
  html body .aj--focus .aj__side { display: none; }
  /* The reader's panel moves below the lesson (7 Nov 2026, one reader for every course): two cards side by side, one
     under 900 px; the headings list stays with the lesson on a wide screen only. As ap-lessons.js .apl-side. */
  /* .aj__grid.sh-reader, as specific as the two-column rule above: until 7 Nov that rule still won here, so under
     1180 px the lesson sat in a squeezed first column (0 px wide on a phone) next to the hidden panel's 316 px. */
  html body .aj__grid.sh-reader { grid-template-columns: minmax(0, 1fr); }
  html body .sh-reader > .aj__side { position: static; top: auto !important; order: 1; max-height: none; overflow: visible; display: grid; grid-template-columns: 1fr 1fr; gap: 18px; align-items: start; padding: 28px 0 0; }
  html body .sh-reader > .aj__side:empty { display: none; }
  html body .sh-reader > .aj__side .ocm-pos, html body .sh-reader > .aj__side .ocm-card { margin: 0; }
  html body .sh-reader > .aj__side .ocm-card:has(.ocm-toc) { display: none; }
}
@media (max-width: 900px) { html body .sh-reader > .aj__side { grid-template-columns: minmax(0, 1fr); } }
@media (max-width: 900px) { html body .aj-fb__full { display: none; } }

/* 5. Previous / Next ------------------------------------------------------------------------ */
/* ONE QUIET BAR, PINNED (Vincent, 7 Nov 2026: "make Next and Back buttons sticky on all modules", then "a little bit
   more subtle"). The lesson's own Back / Previous and Next stay at the bottom of the reading column while you read, in
   every reader (Options Course, analyst and quant, module portals): a slim translucent cream band with a hairline on
   top, no shadow; Back / Previous a plain text link, Next a compact outline button with the next lesson's title in
   small type. It sits in the lesson column only, so it never reaches the right panel; at the end of the lesson it rests
   in its place under the test. Over the phone's home bar it keeps the safe area; there both links are 40 px tall and
   show only their label ("← Previous", "Next →", from the course CSS). */
html body .ocm-nav, html body .apl .ocm-nav { position: sticky; bottom: 0; z-index: 20; display: flex; flex-wrap: nowrap; align-items: center; justify-content: flex-start; gap: 18px;
  max-width: none; margin: 28px 0 0; padding: 7px 0 calc(7px + env(safe-area-inset-bottom, 0px)); border: 0; border-top: 1px solid var(--sh-line); border-radius: 0; box-shadow: none;
  background: rgba(246,243,238,.9); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); }
html body .ocm-nav a, html body .apl .ocm-nav a, html body .ocm-nav a.next, html body .apl .ocm-nav a.next {
  flex: 0 1 auto; width: auto; min-width: 0; max-width: calc(50% - 9px); box-sizing: border-box; margin: 0; padding: 6px 0; text-align: left;
  border: 0; border-radius: var(--sh-r); background: none; box-shadow: none; color: var(--sh-ink-soft);
  font-family: var(--sph-sans, 'Chivo', system-ui, sans-serif); font-size: .8rem; font-weight: 400; line-height: 1.4; letter-spacing: 0; text-transform: none; text-decoration: none;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
html body .ocm-nav a span, html body .apl .ocm-nav a span { display: inline; margin: 0 7px 0 0; font-size: .75rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--sh-muted); }
html body .ocm-nav a:not(.next) span::before, html body .apl .ocm-nav a:not(.next) span::before { content: '\2190\00a0'; }
html body .ocm-nav a:not(.next):hover, html body .ocm-nav a:not(.next):hover span { color: var(--sh-accent); }
html body .ocm-nav a.next, html body .apl .ocm-nav a.next { padding: 6px 13px; border: 1px solid var(--sh-accent); background: transparent; color: var(--sh-accent); font-weight: 600; }
html body .ocm-nav a.next span, html body .apl .ocm-nav a.next span { color: var(--sh-accent); }
html body .ocm-nav a.next:hover, html body .apl .ocm-nav a.next:hover { background: var(--sh-accent); color: var(--sh-on-accent); }
html body .ocm-nav a.next:hover span, html body .apl .ocm-nav a.next:hover span { color: var(--sh-on-accent); }
@media (max-width: 560px) {
  html body .ocm-nav, html body .apl .ocm-nav { justify-content: space-between; gap: 10px; }
  html body .ocm-nav a, html body .apl .ocm-nav a, html body .ocm-nav a.next, html body .apl .ocm-nav a.next { display: inline-flex; align-items: center; min-height: 40px; max-width: none; flex: 0 1 auto; font-size: 0; }
  html body .ocm-nav a:not(.next), html body .apl .ocm-nav a:not(.next) { padding: 0 6px 0 0; }
  html body .ocm-nav a.next, html body .apl .ocm-nav a.next { padding: 0 16px; }
  html body .ocm-nav a span, html body .apl .ocm-nav a span { margin: 0; font-size: .75rem; }
}

/* 6. Tests and buttons ---------------------------------------------------------------------- */
html body .ocm-test, html body .ocm-test .ocp-btn, html body .ocp-quiz__opt, html body .ocm-chk .ocp-btn,
html body .apl .ocp-btn, html body .apl .ocm-test { border-radius: var(--sh-r); }

/* 7. Resource list -------------------------------------------------------------------------- */
/* The Resources tab of every program (Vincent, 20 Oct 2026: "sven resources should also look like [the analyst
   one] ... this is what i meant with consistency"): groups with a small burgundy head, then a chain of numbered
   nodes on one rail, each with a card (logo tile, title, line, stage chip). Values are the analyst portal's own
   (ap-inperson.js renderResources). Markup:
   <div class="ap-res-group"><div class="ap-res-ghead">Group</div><div class="ap-res-chain">
     <div class="ap-res-link"><span class="ap-res-node">1</span>
       <a|button class="ao-mini ap-tool"><span class="ap-tool__logo">svg</span><span class="ap-tool__meta">
         <span class="ao-row__t">Title</span><span class="ao-row__s">Line</span><span class="ap-res-stage">svg Stage</span></span></a></div>
   </div></div> */
.ao-sub { font-size: .92rem; color: var(--sh-muted); margin: 0 0 1.25rem; line-height: 1.5; }
.ap-res-group { margin-top: 22px; } .ap-res-group:first-child { margin-top: 6px; }
.ap-res-ghead { font-size: .7rem; font-weight: 800; text-transform: uppercase; letter-spacing: .8px; color: var(--sh-accent); padding-bottom: 6px; margin-bottom: 12px; border-bottom: 1px solid var(--sh-hairline, #eef0f2); }
.ap-res-chain { position: relative; display: flex; flex-direction: column; gap: 13px; }
.ap-res-chain::before { content: ""; position: absolute; left: 15px; top: 16px; bottom: 16px; width: 2px; background: #e5e7eb; z-index: 0; }
.ap-res-link { position: relative; z-index: 1; display: flex; align-items: center; gap: 14px; }
.ap-res-node { width: 30px; height: 30px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: .85rem; font-weight: 800; background: var(--sh-surface, #fff); color: var(--sh-accent); border: 2px solid var(--sh-accent); flex-shrink: 0; }
.ap-res-node--lock { color: #9ca3af; border-color: #e5e7eb; }
.ap-res-node--lock svg { width: 14px; height: 14px; }
.ap-res-stage { display: inline-flex; align-items: center; gap: 5px; align-self: flex-start; font-size: .7rem; font-weight: 700; color: #6b7280; margin-top: 1px; }
.ap-res-stage svg { width: 12px; height: 12px; flex-shrink: 0; }
.ap-res-stage--lock { color: #9ca3af; }
.ao-mini { border: 1px solid var(--sh-line); border-radius: 14px; padding: 14px; background: var(--sh-surface, #fff); }
.ap-tool { position: relative; display: flex; align-items: center; gap: 11px; flex: 1; min-width: 0; transition: border-color .15s, box-shadow .15s, transform .15s; }
button.ap-tool { font: inherit; color: inherit; text-align: left; cursor: pointer; }
a.ap-tool { text-decoration: none; }
.ap-tool:hover { border-color: #d1d5db; box-shadow: 0 6px 16px rgba(0,0,0,.08); transform: translateX(3px); }
.ap-tool:disabled { cursor: progress; opacity: .7; }
.ap-tool__logo { width: 34px; height: 34px; border-radius: 8px; background: var(--sh-surface, #fff); border: 1px solid #e5e7eb; display: flex; align-items: center; justify-content: center; flex-shrink: 0; color: var(--sh-ink); }
.ap-tool__meta { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.ao-row__t { font-weight: 700; font-size: .94rem; color: var(--sh-ink); }
.ao-row__s { font-size: .8rem; color: var(--sh-muted); margin-top: 2px; }

/* 9. THE MENU'S FOLDS AND COURSES (3 Nov 2026, assets/sph-menu.js). Courses and Tools fold open like Canvas's
   menu; the sidebar keeps its width (--sh-side) and the tabs their look. A top-level item may carry a 16px icon
   (.sh-ic); a fold button ends in a chevron that turns when open. */
html body .ao-tabs .sh-ic { width: 16px; height: 16px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; opacity: .85; }
html body .ao-tabs .sh-chev { width: 14px; height: 14px; flex: none; margin-left: auto; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; transition: transform .15s; }
html body .ao-tabs .sh-fold__btn[aria-expanded="true"] .sh-chev { transform: rotate(90deg); }
html body .ao-tabs .sh-fold__body { display: flex; flex-direction: column; gap: 2px; margin: 2px 0 6px 20px; padding-left: 8px; border-left: 1px solid var(--sh-line); }
html body .ao-tabs .sh-fold__body[hidden] { display: none; }
html body .ao-tabs .sh-fold__body .ao-tab { font-weight: 500; }
html body .ao-tabs .sh-fold__body .ao-tab.active { font-weight: 600; }
html body .ao-tabs .sh-course { flex-direction: column; align-items: flex-start; gap: 4px; white-space: normal; line-height: 1.25; }
html body .ao-tabs .sh-course small { font-size: .75rem; font-weight: 500; opacity: .75; }
html body .ao-tabs .sh-sep { border-top: 1px solid var(--sh-line); margin: 8px 4px; }
@media (max-width: 900px) {
  html body .ao-tabs .sh-fold__body { flex-basis: 100%; flex-direction: row; flex-wrap: wrap; margin: 0 0 6px; padding-left: 0; border-left: 0; }
  html body .ao-tabs .sh-sep { flex-basis: 100%; margin: 4px 0; }
}
/* A course's progress bar under its name in the Courses fold (3 Nov 2026, like the mockup). */
html body .ao-tabs .sh-bar { display: block; align-self: stretch; height: 5px; margin-top: 6px; border-radius: 5px; background: rgba(3,2,72,.08); overflow: hidden; }
html body .ao-tabs .sh-bar i { display: block; height: 100%; background: var(--sh-accent, #66100c); }
html body .ao-tabs .sh-bar.ok i { background: #047857; }
html body .ao-tabs .ao-tab.active .sh-bar { background: rgba(255,255,255,.3); }
html body .ao-tabs .ao-tab.active .sh-bar i { background: #fff; }

/* The course you are in, in the Courses list: marked, not filled, so the menu item below that opens the same page is the
   one filled tab (5 Nov 2026). */
/* The page's own entry (data-sh-own, 5 Nov 2026) is always the marked one: it opens this portal's Home, the lessons have their own item. */
html body .ao-tabs .sh-courses-body .ao-tab.sh-course[data-sh-own],
html body .ao-tabs .sh-courses-body .ao-tab.sh-course.active { background: transparent; color: #66100c; font-weight: 700; box-shadow: inset 3px 0 0 #66100c; border-radius: 0 6px 6px 0; }
html body .ao-tabs .sh-courses-body .ao-tab.sh-course[data-sh-own] small,
html body .ao-tabs .sh-courses-body .ao-tab.sh-course.active small { color: #6b625f; }

/* 10. THE LESSONS LIST, LIKE OBJECTIVES (Vincent, 5 Nov 2026: "can the way lessons are displayed be slightly changed to
   match our new style a bit more ... match objectives a bit"). The Journey of the analyst and quant portals and the Options
   Course modules (.aj) take the Objectives look of assets/sph-canvas.css: white cards on a paper header, the number in a
   small square, sans bold row titles, round soft status labels, sentence case. Section titles stay Cardo (rule book 2).
   Scoped under .aj so it wins over sph-portal.css and aj-journey.css without !important. */
html body .aj .aj-sec { background: #fff; border: 1px solid rgba(3,2,72,.14); border-radius: 12px; box-shadow: none; }
html body .aj .aj-sec--active { border-color: rgba(102,16,12,.45); border-top-width: 1px; box-shadow: none; }
html body .aj .aj-sec > .aj-sec__h, html body .aj .aj-sec--active > .aj-sec__h { background: #fbf9f5; border-bottom-color: rgba(3,2,72,.14); }
html body .aj .aj-sec--folded > .aj-sec__h, html body .aj .aj-sec--line > .aj-sec__h { border-bottom: 0; }
html body .aj .aj-sec__n {
  display: grid; place-items: center; width: 32px; height: 32px; padding: 0; border-radius: 6px;
  background: rgba(102,16,12,.06); color: #66100c; font: 800 .85rem/1 'Chivo', system-ui, sans-serif; letter-spacing: 0;
}
html body .aj .aj-sec--line .aj-sec__n { width: 28px; height: 28px; font-size: .8rem; }
html body .aj .aj-sec__t { font-size: 1.35rem; }
html body .aj .aj-sec--line .aj-sec__t { font-size: 1.12rem; }
html body .aj .aj-sec__m { font-size: .85rem; }
html body .aj .aj-row { background: #fff; }
html body .aj .aj-row:hover { background: rgba(102,16,12,.04); }
html body .aj .aj-row__n {
  display: inline-grid; place-items: center; justify-self: start; min-width: 28px; height: 28px; padding: 0 6px; border-radius: 6px;
  background: rgba(102,16,12,.06); color: #66100c; font: 700 .75rem/1 'Chivo', system-ui, sans-serif; letter-spacing: 0;
}
html body .aj .aj-row--done .aj-row__n { background: #d1fae5; color: #047857; }
html body .aj .aj-row__n--date { background: transparent; color: rgba(26,20,16,.62); padding: 0; min-width: 0; }
html body .aj .aj-row__t { font: 700 1rem/1.35 'Chivo', system-ui, sans-serif; color: #030248; }
html body .aj .aj-row--missed .aj-row__t { color: #a16207; }
/* Status labels: the Objectives pill (rule book 4). */
html body .aj .aj-st {
  border: 0; border-radius: 999px; padding: 6px 12px; background: #f1f1f4; color: #4b5563;
  font: 700 .75rem/1.2 'Chivo', system-ui, sans-serif; letter-spacing: 0; text-transform: none;
}
html body .aj .aj-st--ok { background: #d1fae5; color: #047857; }
html body .aj .aj-st--next { background: rgba(102,16,12,.08); color: #66100c; }
html body .aj .aj-st--warn { background: #fef3c7; color: #a16207; }
html body .aj .aj-st--no { background: #fee2e2; color: #b91c1c; }
/* Tags and buttons in a section head: sentence case, as on Objectives. */
html body .aj .aj-sec__tag { border-radius: 999px; padding: 0 12px; letter-spacing: 0; text-transform: none; font-size: .75rem; }
html body .aj .aj-btn, html body .aj .aj-sec__link, html body .aj a.aj-sec__link { text-transform: none; letter-spacing: 0; font-size: .8rem; border-radius: 2px; }
/* One title line for open and folded sections (the folded ones started 14px further left). */
html body .aj .aj-sec--line .aj-sec__h { grid-template-columns: 66px minmax(0,1fr) auto auto; padding-left: 22px; }
@media (max-width: 640px) {
  html body .aj .aj-sec--line .aj-sec__h { grid-template-columns: 44px minmax(0,1fr) auto; padding-left: 14px; }
}

/* 11. ONE LOOK IN EVERY TAB (5 Nov 2026, Vincent: "check throughout whole portal if all styles match and for all portals").
   The shapes of the Objectives list, applied to the parts that had their own: status chips are round and sentence case,
   cards and tiles have 12 px corners, buttons 2 px, labels grey small capitals, no gradients, no coloured stripes.
   Colours that carry a state (green, amber, red, grey) stay as each part sets them. PORTAL_RULEBOOK.md section 2 and 5c. */
:root { --sph-serif: 'Cardo', Georgia, 'Times New Roman', serif; }
/* Status chips (Calendar, Portfolio, Risk, Voting, Data flow, module pages, Options Course progress, ticker lists). */
html body .ao-pill, html body .aop-status, html body .sph-el__chip, html body .ocp-ql__s, html body .aql-pill, html body .apo-tkg__st {
  border-radius: 999px; padding: 5px 11px; font-family: 'Chivo', system-ui, sans-serif; font-size: .75rem; font-weight: 700;
  line-height: 1.2; letter-spacing: 0; text-transform: none; border-width: 0;
}
html body .aop-status.voting { background: rgba(102,16,12,.08); color: #66100c; }
html body .aql-pill--paper { background: #f1f1f4; color: #4b5563; }
html body .aql-pill--live { background: #d1fae5; color: #047857; }
/* The lesson reader's headings: Cardo in ink, as every page title (rule book 2). */
html body .apl, html body #ao-journey { --m-serif: 'Cardo', Georgia, 'Times New Roman', serif; --m-ink: #030248; }
/* The Options Course reader (#ao-journey, audit 6 Nov 2026): Cardo headings at weight 400, in ink, no Newsreader. */
html body #ao-journey .ocm-lesson h1, html body #ao-journey .ocm-lesson h2, html body #ao-journey .ocm-lesson .try h4,
html body #ao-journey .ocm-test__h h2, html body #ao-journey .ocm-test .ocp-quiz h3 { font-family: 'Cardo', Georgia, serif; font-weight: 400; font-variation-settings: normal; color: var(--m-ink); }
html body .apl .ocm-lesson h1, html body .apl .ocm-lesson h2, html body .apl .ocm-test__h h2, html body .apl .ocm-test .ocp-quiz h3 { font-weight: 400; font-variation-settings: normal; }
/* Cards and tiles: 12 px corners, a 1 px line, no top or left stripes. */
html body .apsc-tile, html body .apm-tile, html body .aql-node, html body .aql-proj, html body .aql-run, html body .sph-el__step { border-radius: 12px; }
html body .aql-proj, html body .aql-proj--full { border-top: 1px solid rgba(3,2,72,.14); }
html body .ap-feat .aop-card.ap-cal-target, html body .ap-feat .aop-card.ap-cal-meeting, html body .aop-card.ap-cal-target, html body .aop-card.ap-cal-meeting { border-left: 1px solid rgba(3,2,72,.14); }
/* Gold is for credentials only: the Data flow labels and accents go grey and burgundy. */
html body .aql { --aql-gold: rgba(26,20,16,.62); }
/* Buttons: 2 px corners. Filter chips: the Objectives chips. */
html body .apr .btn, html body .apr-livebtn, html body .aql-btn { border-radius: 2px; }
html body .aql-filt button { border-radius: 999px; }
/* Labels: grey small capitals in Chivo. */
html body .apr .k, html body .ap-rc__cyc, html body .mp-cert__k, html body .sph-el__k, html body .ocp-ql__h {
  font-family: 'Chivo', system-ui, sans-serif; font-size: .75rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: rgba(26,20,16,.62);
}
/* Notice panels on Team: flat paper, a 1 px line, 12 px corners; the state is in the text and its pill. */
html body .ap-tsw--open, html body .ap-rc, html body .apr-hb { background: #fbf9f5; background-image: none; border: 1px solid rgba(3,2,72,.14); border-radius: 12px; }
/* Countdown tiles: paper with Chivo numbers, never dark. */
html body .apr-count div { background: #fbf9f5; color: #030248; border: 1px solid rgba(3,2,72,.14); font-family: 'Chivo', system-ui, sans-serif; }
/* Role and seat tags are names, not states: neutral, round, sentence case. */
html body .ao-mem-role { border-radius: 999px; background: #f1f1f4; color: #4b5563; border-color: transparent; text-transform: none; letter-spacing: 0; }
/* Resources: the timeline dots become the Objectives number squares. */
html body .ap-res-node { width: 28px; height: 28px; border-radius: 6px; border: 0; background: rgba(102,16,12,.06); font-size: .75rem; }
/* File pickers. */
html body input[type=file]::file-selector-button { border: 1px solid #66100c; background: #fff; color: #66100c; border-radius: 2px; padding: 7px 12px; font: 700 .8rem 'Chivo', system-ui, sans-serif; cursor: pointer; margin-right: 10px; }
/* Options Course About cards: white cards. */
html body .ocp-link { background: #fff; border: 1px solid rgba(3,2,72,.14); border-radius: 12px; }
/* Options Course Live Q&A: a white card with the photo on the right, not a dark block (rule book 5c). */
html body .ocp-qa__hero { background: #fff; color: #1a1410; border: 1px solid rgba(3,2,72,.14); border-radius: 12px; }
html body .ocp-qa__when { color: #030248; }
html body .ocp-qa__note { color: rgba(26,20,16,.72); }
html body .ocp-qa__acts a, html body .ocp-qa__acts button { border-radius: 2px; text-transform: none; letter-spacing: 0; font-size: .85rem; border: 1px solid #66100c; color: #66100c; background: #fff; }
html body .ocp-qa__acts a.join, html body .ocp-qa__acts button.join { background: #66100c; color: #fff; border-color: #66100c; }
html body .ocp-qa__acts button.ocp-qa__cancel { border-color: transparent; color: rgba(26,20,16,.62); background: transparent; }
/* Calendar rows: no coloured left stripe (the session rows are .ao-row). A test to retry is amber, not a filled burgundy block. */
html body .ap-feat .ao-row.ap-cal-meeting { border-left: 1px solid rgba(3,2,72,.14); }
html body .ocp-ql__s--retry { background: #fef3c7; color: #a16207; }

/* ONE READING COLUMN FOR EVERY COURSE (7 Nov 2026, Vincent: "not all module content same width ... macro not same width
   as analyst or quant"; and "most text is left and all of a sudden centered images and cards"). Measured in his browser:
   the macro reader's lesson was 720 px with its figure centred in it; the analyst reader's lesson ran 2212 px wide with a
   68ch (803 px) lede and its figure centred in the 2212. Now every reader (Analyst and Quant programs, the macro course,
   Reading a Business, the Options Course) has the same 720 px lesson column on the left of its reading area, and text,
   figures, cards and infographics all start at its left edge. */
html body .ocm-lesson, html body .apl .ocm-lesson, html body .sh-reader .ocm-lesson, html body .aj--focus .apl .ocm-lesson {
  max-width: 720px !important; margin-left: 0 !important; margin-right: auto !important; }
html body .ocm-lesson .mm-fig, html body .ocm-lesson figure, html body .ocm-lesson .apl-pdf {
  margin-left: 0 !important; margin-right: auto !important; }
html body .ocm-lesson .mm-fig img { margin-left: 0 !important; margin-right: auto !important; }
html body .ocm-lesson figcaption { text-align: left !important; }
html body .ocm-lesson .mm-fig.ig { max-width: 100% !important; }
/* LESSON FIGURES AT THE FULL WIDTH OF THAT COLUMN (7 Nov 2026, after every course's figures were redrawn as 2400x1350
   PNGs): one image per figure fills the 720 px column, left-aligned with the text, height from the picture, no 600 px /
   340 px cap. Covers the analyst and quant engines (.mm-fig), Reading a Business charts (.rb-fig--chart, whose inline
   max-width:680px this beats) and the Options Course lessons (figure.fig with a picture, now framed like .mm-fig instead
   of a padded card). Not touched: photo rows (their tiles sit in a grid inside the figure, not as its direct image), the
   Reading a Business pair of sheets (.rb-figs), the portrait report pages (.mm-fig--narrow, 440 px) and video players.
   The standalone module pages carry the same rule in options-course/assets/modules.css. */
html body .ocm-lesson figure.mm-fig, html body .ocm-lesson figure.rb-fig--chart, html body .ocm-lesson figure.fig:has(> img) {
  width: 100% !important; max-width: 100% !important; box-sizing: border-box; }
html body .ocm-lesson figure.mm-fig > img, html body .ocm-lesson figure.rb-fig--chart img, html body .ocm-lesson figure.fig > img {
  width: 100% !important; max-width: 100% !important; height: auto !important; max-height: none !important; object-fit: fill !important; box-sizing: border-box; }
html body .ocm-lesson figure.mm-fig--narrow { max-width: 440px !important; }
html body .ocm-lesson figure.fig:has(> img) { padding: 0 !important; border: 0 !important; background: none !important; }
html body .ocm-lesson figure.fig > img { border: 1px solid var(--m-line, rgba(3,2,72,.14)); border-radius: 0 !important; }
html body .ocm-lesson figure.fig:has(> img) figcaption { margin: 8px 0 0 !important; }

/* 12. THE CERTIFICATE PAGE (7 Nov 2026, Vincent: "so make all consistent please"). One block for the Certificate tab of all
   five portals: a white card with the grey label "The certificate", the certificate's name in Cardo, then the sample (or
   the member's own) certificate with its badge bottom-right beside the text and the five ticks (its own credential ID,
   sophron.eu/verify, the public register, LinkedIn, the profile badge); then a second card with the member's progress or
   the hand-in. Used by the module portals (sph-module-portal.js certIntro), the Analyst and Quant Program (analyst/portal.html
   paintCertPage) and the Options Course (data-body="cert"). The first two carry the same values inline; this copy is the one
   a portal without them (the Options Course) reads. Specific enough to beat `.ocp-modal .ocp-cert img`. */
html body .mp-cert { background: #fff; border: 1px solid rgba(3,2,72,.14); border-radius: 12px; padding: 20px 22px; margin: 0 0 20px; box-sizing: border-box; }
html body .mp-cert .mp-cert__k { margin: 0 0 6px; font: 700 .75rem/1.3 'Chivo', system-ui, sans-serif; letter-spacing: .14em; text-transform: uppercase; color: rgba(26,20,16,.62); }
html body .mp-cert .mp-cert__t { margin: 0 0 20px; font-family: 'Cardo', Georgia, serif; font-weight: 400; font-size: 1.9rem; line-height: 1.2; color: #030248; }
html body .mp-cert .mp-cert__t sup { font-size: .5em; }
html body .mp-cert .mp-cert__grid { display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); gap: 32px; align-items: start; }
html body .mp-cert .mp-cert__art { position: relative; margin: 0 0 24px; }
html body .mp-cert img.mp-cert__img { display: block; width: 100%; max-width: none; height: auto; border: 0; border-radius: 4px; box-shadow: 0 2px 6px rgba(42,37,35,.08), 0 14px 32px rgba(42,37,35,.12); }
html body .mp-cert img.mp-cert__badge { position: absolute; right: -14px; bottom: -22px; width: 96px; height: 96px; max-width: none; object-fit: contain; border: 0; border-radius: 0; box-shadow: none; filter: drop-shadow(0 8px 16px rgba(42,37,35,.25)); }
html body .mp-cert .mp-cert__p { margin: 0 0 14px; font-size: .95rem; line-height: 1.6; color: #3b3330; }
html body .mp-cert .mp-cert__ticks { list-style: none; margin: 0; padding: 0; }
html body .mp-cert .mp-cert__ticks li { position: relative; padding: 0 0 10px 26px; line-height: 1.55; color: #3b3330; font-size: .92rem; }
html body .mp-cert .mp-cert__ticks li::before { content: ''; position: absolute; left: 3px; top: 7px; width: 10px; height: 6px; border-left: 2px solid #66100c; border-bottom: 2px solid #66100c; transform: rotate(-45deg); }
html body .mp-cert .mp-cert__ticks b { color: #030248; }
html body .mp-cert .mp-cert__ticks a { color: #66100c; }
@media (max-width: 900px) { html body .mp-cert .mp-cert__grid { grid-template-columns: minmax(0, 1fr); gap: 8px; } html body .mp-cert img.mp-cert__badge { right: 0; width: 76px; height: 76px; } }
@media (max-width: 640px) { html body .mp-cert .mp-cert__t { font-size: 1.6rem; } }
